summaryrefslogtreecommitdiffstats
path: root/tests/ui/unsized-locals
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/unsized-locals
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/unsized-locals')
-rw-r--r--tests/ui/unsized-locals/autoderef.rs49
-rw-r--r--tests/ui/unsized-locals/auxiliary/ufuncs.rs3
-rw-r--r--tests/ui/unsized-locals/borrow-after-move.rs43
-rw-r--r--tests/ui/unsized-locals/borrow-after-move.stderr85
-rw-r--r--tests/ui/unsized-locals/box-fnonce.rs10
-rw-r--r--tests/ui/unsized-locals/by-value-trait-object-safety-rpass.rs25
-rw-r--r--tests/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs23
-rw-r--r--tests/ui/unsized-locals/by-value-trait-object-safety.rs22
-rw-r--r--tests/ui/unsized-locals/by-value-trait-object-safety.stderr20
-rw-r--r--tests/ui/unsized-locals/double-move.rs54
-rw-r--r--tests/ui/unsized-locals/double-move.stderr86
-rw-r--r--tests/ui/unsized-locals/issue-30276-feature-flagged.rs8
-rw-r--r--tests/ui/unsized-locals/issue-30276-feature-flagged.stderr22
-rw-r--r--tests/ui/unsized-locals/issue-30276.rs5
-rw-r--r--tests/ui/unsized-locals/issue-30276.stderr13
-rw-r--r--tests/ui/unsized-locals/issue-50940-with-feature.rs8
-rw-r--r--tests/ui/unsized-locals/issue-50940-with-feature.stderr26
-rw-r--r--tests/ui/unsized-locals/issue-50940.rs5
-rw-r--r--tests/ui/unsized-locals/issue-50940.stderr13
-rw-r--r--tests/ui/unsized-locals/reference-unsized-locals.rs10
-rw-r--r--tests/ui/unsized-locals/simple-unsized-locals.rs9
-rw-r--r--tests/ui/unsized-locals/suggest-borrow.rs7
-rw-r--r--tests/ui/unsized-locals/suggest-borrow.stderr60
-rw-r--r--tests/ui/unsized-locals/unsized-exprs-rpass.rs33
-rw-r--r--tests/ui/unsized-locals/unsized-exprs.rs28
-rw-r--r--tests/ui/unsized-locals/unsized-exprs.stderr41
-rw-r--r--tests/ui/unsized-locals/unsized-exprs2.rs24
-rw-r--r--tests/ui/unsized-locals/unsized-exprs2.stderr12
-rw-r--r--tests/ui/unsized-locals/unsized-exprs3.rs10
-rw-r--r--tests/ui/unsized-locals/unsized-exprs3.stderr13
-rw-r--r--tests/ui/unsized-locals/unsized-index.rs27
-rw-r--r--tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs15
-rw-r--r--tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr37
-rw-r--r--tests/ui/unsized-locals/unsized-parameters.rs13
34 files changed, 859 insertions, 0 deletions
diff --git a/tests/ui/unsized-locals/autoderef.rs b/tests/ui/unsized-locals/autoderef.rs
new file mode 100644
index 000000000..5dd5898c1
--- /dev/null
+++ b/tests/ui/unsized-locals/autoderef.rs
@@ -0,0 +1,49 @@
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(unsized_locals, unsized_fn_params)]
+
+pub trait Foo {
+ fn foo(self) -> String;
+}
+
+impl Foo for [char] {
+ fn foo(self) -> String {
+ self.iter().collect()
+ }
+}
+
+impl Foo for str {
+ fn foo(self) -> String {
+ self.to_owned()
+ }
+}
+
+impl Foo for dyn FnMut() -> String {
+ fn foo(mut self) -> String {
+ self()
+ }
+}
+
+fn main() {
+ let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>);
+ assert_eq!(&x.foo() as &str, "hello");
+
+ let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>;
+ assert_eq!(&x.foo() as &str, "hello");
+
+ let x = "hello".to_owned().into_boxed_str();
+ assert_eq!(&x.foo() as &str, "hello");
+
+ let x = *("hello".to_owned().into_boxed_str());
+ assert_eq!(&x.foo() as &str, "hello");
+
+ let x = "hello".to_owned().into_boxed_str();
+ assert_eq!(&x.foo() as &str, "hello");
+
+ let x = *(Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>);
+ assert_eq!(&x.foo() as &str, "hello");
+
+ let x = Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>;
+ assert_eq!(&x.foo() as &str, "hello");
+}
diff --git a/tests/ui/unsized-locals/auxiliary/ufuncs.rs b/tests/ui/unsized-locals/auxiliary/ufuncs.rs
new file mode 100644
index 000000000..5954abf3a
--- /dev/null
+++ b/tests/ui/unsized-locals/auxiliary/ufuncs.rs
@@ -0,0 +1,3 @@
+#![feature(unsized_locals, unsized_fn_params)]
+
+pub fn udrop<T: ?Sized>(_x: T) {}
diff --git a/tests/ui/unsized-locals/borrow-after-move.rs b/tests/ui/unsized-locals/borrow-after-move.rs
new file mode 100644
index 000000000..ad73b720f
--- /dev/null
+++ b/tests/ui/unsized-locals/borrow-after-move.rs
@@ -0,0 +1,43 @@
+#![feature(unsized_locals, unsized_fn_params)]
+//~^ WARN the feature `unsized_locals` is incomplete
+
+pub trait Foo {
+ fn foo(self) -> String;
+}
+
+impl Foo for str {
+ fn foo(self) -> String {
+ self.to_owned()
+ }
+}
+
+fn drop_unsized<T: ?Sized>(_: T) {}
+
+fn main() {
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ let y = *x;
+ drop_unsized(y);
+ println!("{}", &x);
+ //~^ERROR borrow of moved value
+ println!("{}", &y);
+ //~^ERROR borrow of moved value
+ }
+
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ let y = *x;
+ y.foo();
+ println!("{}", &x);
+ //~^ERROR borrow of moved value
+ println!("{}", &y);
+ //~^ERROR borrow of moved value
+ }
+
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ x.foo();
+ println!("{}", &x);
+ //~^ERROR borrow of moved value
+ }
+}
diff --git a/tests/ui/unsized-locals/borrow-after-move.stderr b/tests/ui/unsized-locals/borrow-after-move.stderr
new file mode 100644
index 000000000..9e3c345dd
--- /dev/null
+++ b/tests/ui/unsized-locals/borrow-after-move.stderr
@@ -0,0 +1,85 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/borrow-after-move.rs:1:12
+ |
+LL | #![feature(unsized_locals, unsized_fn_params)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0382]: borrow of moved value: `x`
+ --> $DIR/borrow-after-move.rs:21:24
+ |
+LL | let y = *x;
+ | -- value moved here
+LL | drop_unsized(y);
+LL | println!("{}", &x);
+ | ^^ value borrowed here after move
+ |
+ = note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of moved value: `y`
+ --> $DIR/borrow-after-move.rs:23:24
+ |
+LL | let y = *x;
+ | - move occurs because `y` has type `str`, which does not implement the `Copy` trait
+LL | drop_unsized(y);
+ | - value moved here
+...
+LL | println!("{}", &y);
+ | ^^ value borrowed here after move
+ |
+note: consider changing this parameter type in function `drop_unsized` to borrow instead if owning the value isn't necessary
+ --> $DIR/borrow-after-move.rs:14:31
+ |
+LL | fn drop_unsized<T: ?Sized>(_: T) {}
+ | ------------ ^ this parameter takes ownership of the value
+ | |
+ | in this function
+
+error[E0382]: borrow of moved value: `x`
+ --> $DIR/borrow-after-move.rs:31:24
+ |
+LL | let y = *x;
+ | -- value moved here
+LL | y.foo();
+LL | println!("{}", &x);
+ | ^^ value borrowed here after move
+ |
+ = note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of moved value: `y`
+ --> $DIR/borrow-after-move.rs:33:24
+ |
+LL | let y = *x;
+ | - move occurs because `y` has type `str`, which does not implement the `Copy` trait
+LL | y.foo();
+ | ----- `y` moved due to this method call
+...
+LL | println!("{}", &y);
+ | ^^ value borrowed here after move
+ |
+note: `Foo::foo` takes ownership of the receiver `self`, which moves `y`
+ --> $DIR/borrow-after-move.rs:5:12
+ |
+LL | fn foo(self) -> String;
+ | ^^^^
+
+error[E0382]: borrow of moved value: `x`
+ --> $DIR/borrow-after-move.rs:40:24
+ |
+LL | let x = "hello".to_owned().into_boxed_str();
+ | - move occurs because `x` has type `Box<str>`, which does not implement the `Copy` trait
+LL | x.foo();
+ | - value moved here
+LL | println!("{}", &x);
+ | ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | x.clone().foo();
+ | ++++++++
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/unsized-locals/box-fnonce.rs b/tests/ui/unsized-locals/box-fnonce.rs
new file mode 100644
index 000000000..8b2f9b4c9
--- /dev/null
+++ b/tests/ui/unsized-locals/box-fnonce.rs
@@ -0,0 +1,10 @@
+// run-pass
+
+fn call_it<T>(f: Box<dyn FnOnce() -> T>) -> T {
+ f()
+}
+
+fn main() {
+ let s = "hello".to_owned();
+ assert_eq!(&call_it(Box::new(|| s)) as &str, "hello");
+}
diff --git a/tests/ui/unsized-locals/by-value-trait-object-safety-rpass.rs b/tests/ui/unsized-locals/by-value-trait-object-safety-rpass.rs
new file mode 100644
index 000000000..b9881defa
--- /dev/null
+++ b/tests/ui/unsized-locals/by-value-trait-object-safety-rpass.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(unsized_locals)]
+
+pub trait Foo {
+ fn foo(self) -> String;
+}
+
+struct A;
+
+impl Foo for A {
+ fn foo(self) -> String {
+ format!("hello")
+ }
+}
+
+fn main() {
+ let x = *(Box::new(A) as Box<dyn Foo>);
+ assert_eq!(x.foo(), format!("hello"));
+
+ // I'm not sure whether we want this to work
+ let x = Box::new(A) as Box<dyn Foo>;
+ assert_eq!(x.foo(), format!("hello"));
+}
diff --git a/tests/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs b/tests/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs
new file mode 100644
index 000000000..957991f85
--- /dev/null
+++ b/tests/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(unsized_locals, unsized_fn_params)]
+
+pub trait Foo {
+ fn foo(self) -> String {
+ format!("hello")
+ }
+}
+
+struct A;
+
+impl Foo for A {}
+
+fn main() {
+ let x = *(Box::new(A) as Box<dyn Foo>);
+ assert_eq!(x.foo(), format!("hello"));
+
+ // I'm not sure whether we want this to work
+ let x = Box::new(A) as Box<dyn Foo>;
+ assert_eq!(x.foo(), format!("hello"));
+}
diff --git a/tests/ui/unsized-locals/by-value-trait-object-safety.rs b/tests/ui/unsized-locals/by-value-trait-object-safety.rs
new file mode 100644
index 000000000..d0ba6944a
--- /dev/null
+++ b/tests/ui/unsized-locals/by-value-trait-object-safety.rs
@@ -0,0 +1,22 @@
+#![feature(unsized_locals)]
+//~^ WARN the feature `unsized_locals` is incomplete
+
+pub trait Foo {
+ fn foo(self) -> String
+ where
+ Self: Sized;
+}
+
+struct A;
+
+impl Foo for A {
+ fn foo(self) -> String {
+ format!("hello")
+ }
+}
+
+fn main() {
+ let x = *(Box::new(A) as Box<dyn Foo>);
+ x.foo();
+ //~^ERROR the `foo` method cannot be invoked on a trait object
+}
diff --git a/tests/ui/unsized-locals/by-value-trait-object-safety.stderr b/tests/ui/unsized-locals/by-value-trait-object-safety.stderr
new file mode 100644
index 000000000..4f13ec7ac
--- /dev/null
+++ b/tests/ui/unsized-locals/by-value-trait-object-safety.stderr
@@ -0,0 +1,20 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/by-value-trait-object-safety.rs:1:12
+ |
+LL | #![feature(unsized_locals)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error: the `foo` method cannot be invoked on a trait object
+ --> $DIR/by-value-trait-object-safety.rs:20:7
+ |
+LL | Self: Sized;
+ | ----- this has a `Sized` requirement
+...
+LL | x.foo();
+ | ^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/unsized-locals/double-move.rs b/tests/ui/unsized-locals/double-move.rs
new file mode 100644
index 000000000..9e46ef9be
--- /dev/null
+++ b/tests/ui/unsized-locals/double-move.rs
@@ -0,0 +1,54 @@
+#![feature(unsized_locals, unsized_fn_params)]
+//~^ WARN the feature `unsized_locals` is incomplete
+
+pub trait Foo {
+ fn foo(self) -> String;
+}
+
+impl Foo for str {
+ fn foo(self) -> String {
+ self.to_owned()
+ }
+}
+
+fn drop_unsized<T: ?Sized>(_: T) {}
+
+fn main() {
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ let y = *x;
+ drop_unsized(y);
+ drop_unsized(y); //~ERROR use of moved value
+ }
+
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ let _y = *x;
+ drop_unsized(x); //~ERROR use of moved value
+ }
+
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ drop_unsized(x);
+ let _y = *x; //~ERROR use of moved value
+ }
+
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ let y = *x;
+ y.foo();
+ y.foo(); //~ERROR use of moved value
+ }
+
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ let _y = *x;
+ x.foo(); //~ERROR use of moved value
+ }
+
+ {
+ let x = "hello".to_owned().into_boxed_str();
+ x.foo();
+ let _y = *x; //~ERROR use of moved value
+ }
+}
diff --git a/tests/ui/unsized-locals/double-move.stderr b/tests/ui/unsized-locals/double-move.stderr
new file mode 100644
index 000000000..49b906bbe
--- /dev/null
+++ b/tests/ui/unsized-locals/double-move.stderr
@@ -0,0 +1,86 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/double-move.rs:1:12
+ |
+LL | #![feature(unsized_locals, unsized_fn_params)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0382]: use of moved value: `y`
+ --> $DIR/double-move.rs:21:22
+ |
+LL | let y = *x;
+ | - move occurs because `y` has type `str`, which does not implement the `Copy` trait
+LL | drop_unsized(y);
+ | - value moved here
+LL | drop_unsized(y);
+ | ^ value used here after move
+ |
+note: consider changing this parameter type in function `drop_unsized` to borrow instead if owning the value isn't necessary
+ --> $DIR/double-move.rs:14:31
+ |
+LL | fn drop_unsized<T: ?Sized>(_: T) {}
+ | ------------ ^ this parameter takes ownership of the value
+ | |
+ | in this function
+
+error[E0382]: use of moved value: `x`
+ --> $DIR/double-move.rs:27:22
+ |
+LL | let _y = *x;
+ | -- value moved here
+LL | drop_unsized(x);
+ | ^ value used here after move
+ |
+ = note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
+
+error[E0382]: use of moved value: `*x`
+ --> $DIR/double-move.rs:33:18
+ |
+LL | let x = "hello".to_owned().into_boxed_str();
+ | - move occurs because `x` has type `Box<str>`, which does not implement the `Copy` trait
+LL | drop_unsized(x);
+ | - value moved here
+LL | let _y = *x;
+ | ^^ value used here after move
+
+error[E0382]: use of moved value: `y`
+ --> $DIR/double-move.rs:40:9
+ |
+LL | let y = *x;
+ | - move occurs because `y` has type `str`, which does not implement the `Copy` trait
+LL | y.foo();
+ | ----- `y` moved due to this method call
+LL | y.foo();
+ | ^ value used here after move
+ |
+note: `Foo::foo` takes ownership of the receiver `self`, which moves `y`
+ --> $DIR/double-move.rs:5:12
+ |
+LL | fn foo(self) -> String;
+ | ^^^^
+
+error[E0382]: use of moved value: `x`
+ --> $DIR/double-move.rs:46:9
+ |
+LL | let _y = *x;
+ | -- value moved here
+LL | x.foo();
+ | ^ value used here after move
+ |
+ = note: move occurs because `*x` has type `str`, which does not implement the `Copy` trait
+
+error[E0382]: use of moved value: `*x`
+ --> $DIR/double-move.rs:52:18
+ |
+LL | let x = "hello".to_owned().into_boxed_str();
+ | - move occurs because `x` has type `Box<str>`, which does not implement the `Copy` trait
+LL | x.foo();
+ | - value moved here
+LL | let _y = *x;
+ | ^^ value used here after move
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/unsized-locals/issue-30276-feature-flagged.rs b/tests/ui/unsized-locals/issue-30276-feature-flagged.rs
new file mode 100644
index 000000000..635d34f82
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-30276-feature-flagged.rs
@@ -0,0 +1,8 @@
+#![feature(unsized_locals)]
+//~^ WARN the feature `unsized_locals` is incomplete
+
+struct Test([i32]);
+
+fn main() {
+ let _x: fn(_) -> Test = Test;
+} //~^the size for values of type `[i32]` cannot be known at compilation time
diff --git a/tests/ui/unsized-locals/issue-30276-feature-flagged.stderr b/tests/ui/unsized-locals/issue-30276-feature-flagged.stderr
new file mode 100644
index 000000000..b6002cf89
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-30276-feature-flagged.stderr
@@ -0,0 +1,22 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-30276-feature-flagged.rs:1:12
+ |
+LL | #![feature(unsized_locals)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/issue-30276-feature-flagged.rs:7:29
+ |
+LL | let _x: fn(_) -> Test = Test;
+ | ^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[i32]`
+ = note: all function arguments must have a statically known size
+ = help: unsized fn params are gated as an unstable feature
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/issue-30276.rs b/tests/ui/unsized-locals/issue-30276.rs
new file mode 100644
index 000000000..9c4bf062a
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-30276.rs
@@ -0,0 +1,5 @@
+struct Test([i32]);
+
+fn main() {
+ let _x: fn(_) -> Test = Test;
+} //~^the size for values of type `[i32]` cannot be known at compilation time
diff --git a/tests/ui/unsized-locals/issue-30276.stderr b/tests/ui/unsized-locals/issue-30276.stderr
new file mode 100644
index 000000000..8cccbd792
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-30276.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/issue-30276.rs:4:29
+ |
+LL | let _x: fn(_) -> Test = Test;
+ | ^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[i32]`
+ = note: all function arguments must have a statically known size
+ = help: unsized fn params are gated as an unstable feature
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/issue-50940-with-feature.rs b/tests/ui/unsized-locals/issue-50940-with-feature.rs
new file mode 100644
index 000000000..63b0e830b
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-50940-with-feature.rs
@@ -0,0 +1,8 @@
+#![feature(unsized_locals, unsized_fn_params)]
+//~^ WARN the feature `unsized_locals` is incomplete
+
+fn main() {
+ struct A<X: ?Sized>(X);
+ A as fn(str) -> A<str>;
+ //~^ERROR the size for values of type `str` cannot be known at compilation time
+}
diff --git a/tests/ui/unsized-locals/issue-50940-with-feature.stderr b/tests/ui/unsized-locals/issue-50940-with-feature.stderr
new file mode 100644
index 000000000..8bbe317ec
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-50940-with-feature.stderr
@@ -0,0 +1,26 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-50940-with-feature.rs:1:12
+ |
+LL | #![feature(unsized_locals, unsized_fn_params)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+ --> $DIR/issue-50940-with-feature.rs:6:5
+ |
+LL | A as fn(str) -> A<str>;
+ | ^ doesn't have a size known at compile-time
+ |
+ = help: within `A<str>`, the trait `Sized` is not implemented for `str`
+note: required because it appears within the type `A<str>`
+ --> $DIR/issue-50940-with-feature.rs:5:12
+ |
+LL | struct A<X: ?Sized>(X);
+ | ^
+ = note: the return type of a function must have a statically known size
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/issue-50940.rs b/tests/ui/unsized-locals/issue-50940.rs
new file mode 100644
index 000000000..7ba809b7e
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-50940.rs
@@ -0,0 +1,5 @@
+fn main() {
+ struct A<X: ?Sized>(X);
+ A as fn(str) -> A<str>;
+ //~^ERROR the size for values of type `str` cannot be known at compilation time
+}
diff --git a/tests/ui/unsized-locals/issue-50940.stderr b/tests/ui/unsized-locals/issue-50940.stderr
new file mode 100644
index 000000000..8f09b460e
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-50940.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+ --> $DIR/issue-50940.rs:3:5
+ |
+LL | A as fn(str) -> A<str>;
+ | ^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `str`
+ = note: all function arguments must have a statically known size
+ = help: unsized fn params are gated as an unstable feature
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/reference-unsized-locals.rs b/tests/ui/unsized-locals/reference-unsized-locals.rs
new file mode 100644
index 000000000..4e887f327
--- /dev/null
+++ b/tests/ui/unsized-locals/reference-unsized-locals.rs
@@ -0,0 +1,10 @@
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(unsized_locals)]
+
+fn main() {
+ let foo: Box<[u8]> = Box::new(*b"foo");
+ let foo: [u8] = *foo;
+ assert_eq!(&foo, b"foo" as &[u8]);
+}
diff --git a/tests/ui/unsized-locals/simple-unsized-locals.rs b/tests/ui/unsized-locals/simple-unsized-locals.rs
new file mode 100644
index 000000000..02b7c299a
--- /dev/null
+++ b/tests/ui/unsized-locals/simple-unsized-locals.rs
@@ -0,0 +1,9 @@
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(unsized_locals)]
+
+fn main() {
+ let foo: Box<[u8]> = Box::new(*b"foo");
+ let _foo: [u8] = *foo;
+}
diff --git a/tests/ui/unsized-locals/suggest-borrow.rs b/tests/ui/unsized-locals/suggest-borrow.rs
new file mode 100644
index 000000000..086948579
--- /dev/null
+++ b/tests/ui/unsized-locals/suggest-borrow.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let x: [u8] = vec!(1, 2, 3)[..]; //~ ERROR E0277
+ let x: &[u8] = vec!(1, 2, 3)[..]; //~ ERROR E0308
+ let x: [u8] = &vec!(1, 2, 3)[..]; //~ ERROR E0308
+ //~^ ERROR E0277
+ let x: &[u8] = &vec!(1, 2, 3)[..];
+}
diff --git a/tests/ui/unsized-locals/suggest-borrow.stderr b/tests/ui/unsized-locals/suggest-borrow.stderr
new file mode 100644
index 000000000..08745eab2
--- /dev/null
+++ b/tests/ui/unsized-locals/suggest-borrow.stderr
@@ -0,0 +1,60 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/suggest-borrow.rs:2:9
+ |
+LL | let x: [u8] = vec!(1, 2, 3)[..];
+ | ^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+ = note: all local variables must have a statically known size
+ = help: unsized locals are gated as an unstable feature
+help: consider borrowing here
+ |
+LL | let x: &[u8] = vec!(1, 2, 3)[..];
+ | +
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-borrow.rs:3:20
+ |
+LL | let x: &[u8] = vec!(1, 2, 3)[..];
+ | ----- ^^^^^^^^^^^^^^^^^
+ | | |
+ | | expected `&[u8]`, found slice `[{integer}]`
+ | | help: consider borrowing here: `&vec!(1, 2, 3)[..]`
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-borrow.rs:4:19
+ |
+LL | let x: [u8] = &vec!(1, 2, 3)[..];
+ | ---- ^^^^^^^^^^^^^^^^^^ expected slice `[u8]`, found `&[{integer}]`
+ | |
+ | expected due to this
+ |
+help: consider removing the borrow
+ |
+LL - let x: [u8] = &vec!(1, 2, 3)[..];
+LL + let x: [u8] = vec!(1, 2, 3)[..];
+ |
+help: alternatively, consider changing the type annotation
+ |
+LL | let x: &[u8] = &vec!(1, 2, 3)[..];
+ | +
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/suggest-borrow.rs:4:9
+ |
+LL | let x: [u8] = &vec!(1, 2, 3)[..];
+ | ^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+ = note: all local variables must have a statically known size
+ = help: unsized locals are gated as an unstable feature
+help: consider borrowing here
+ |
+LL | let x: &[u8] = &vec!(1, 2, 3)[..];
+ | +
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/unsized-exprs-rpass.rs b/tests/ui/unsized-locals/unsized-exprs-rpass.rs
new file mode 100644
index 000000000..175b02fcb
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-exprs-rpass.rs
@@ -0,0 +1,33 @@
+// run-pass
+#![allow(incomplete_features, unused_braces, unused_parens)]
+#![feature(unsized_tuple_coercion, unsized_locals, unsized_fn_params)]
+
+struct A<X: ?Sized>(#[allow(unused_tuple_struct_fields)] X);
+
+fn udrop<T: ?Sized>(_x: T) {}
+fn foo() -> Box<[u8]> {
+ Box::new(*b"foo")
+}
+fn tfoo() -> Box<(i32, [u8])> {
+ Box::new((42, *b"foo"))
+}
+fn afoo() -> Box<A<[u8]>> {
+ Box::new(A(*b"foo"))
+}
+
+impl std::ops::Add<i32> for A<[u8]> {
+ type Output = ();
+ fn add(self, _rhs: i32) -> Self::Output {}
+}
+
+fn main() {
+ udrop::<[u8]>(loop {
+ break *foo();
+ });
+ udrop::<[u8]>(if true { *foo() } else { *foo() });
+ udrop::<[u8]>({ *foo() });
+ udrop::<[u8]>((*foo()));
+ udrop::<[u8]>((*tfoo()).1);
+ *afoo() + 42;
+ udrop as fn([u8]);
+}
diff --git a/tests/ui/unsized-locals/unsized-exprs.rs b/tests/ui/unsized-locals/unsized-exprs.rs
new file mode 100644
index 000000000..1729b9ffa
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-exprs.rs
@@ -0,0 +1,28 @@
+#![feature(unsized_tuple_coercion, unsized_fn_params)]
+
+struct A<X: ?Sized>(X);
+
+fn udrop<T: ?Sized>(_x: T) {}
+fn foo() -> Box<[u8]> {
+ Box::new(*b"foo")
+}
+fn tfoo() -> Box<(i32, [u8])> {
+ Box::new((42, *b"foo"))
+}
+fn afoo() -> Box<A<[u8]>> {
+ Box::new(A(*b"foo"))
+}
+
+impl std::ops::Add<i32> for A<[u8]> {
+ type Output = ();
+ fn add(self, _rhs: i32) -> Self::Output {}
+}
+
+fn main() {
+ udrop::<(i32, [u8])>((42, *foo()));
+ //~^ERROR E0277
+ udrop::<A<[u8]>>(A { 0: *foo() });
+ //~^ERROR E0277
+ udrop::<A<[u8]>>(A(*foo()));
+ //~^ERROR E0277
+}
diff --git a/tests/ui/unsized-locals/unsized-exprs.stderr b/tests/ui/unsized-locals/unsized-exprs.stderr
new file mode 100644
index 000000000..a7f57e3fd
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-exprs.stderr
@@ -0,0 +1,41 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/unsized-exprs.rs:22:26
+ |
+LL | udrop::<(i32, [u8])>((42, *foo()));
+ | ^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: within `({integer}, [u8])`, the trait `Sized` is not implemented for `[u8]`
+ = note: required because it appears within the type `({integer}, [u8])`
+ = note: tuples must have a statically known size to be initialized
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/unsized-exprs.rs:24:22
+ |
+LL | udrop::<A<[u8]>>(A { 0: *foo() });
+ | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]`
+note: required because it appears within the type `A<[u8]>`
+ --> $DIR/unsized-exprs.rs:3:8
+ |
+LL | struct A<X: ?Sized>(X);
+ | ^
+ = note: structs must have a statically known size to be initialized
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/unsized-exprs.rs:26:22
+ |
+LL | udrop::<A<[u8]>>(A(*foo()));
+ | ^ doesn't have a size known at compile-time
+ |
+ = help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]`
+note: required because it appears within the type `A<[u8]>`
+ --> $DIR/unsized-exprs.rs:3:8
+ |
+LL | struct A<X: ?Sized>(X);
+ | ^
+ = note: the return type of a function must have a statically known size
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/unsized-exprs2.rs b/tests/ui/unsized-locals/unsized-exprs2.rs
new file mode 100644
index 000000000..127d8717e
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-exprs2.rs
@@ -0,0 +1,24 @@
+#![feature(unsized_tuple_coercion, unsized_fn_params)]
+
+struct A<X: ?Sized>(X);
+
+fn udrop<T: ?Sized>(_x: T) {}
+fn foo() -> Box<[u8]> {
+ Box::new(*b"foo")
+}
+fn tfoo() -> Box<(i32, [u8])> {
+ Box::new((42, *b"foo"))
+}
+fn afoo() -> Box<A<[u8]>> {
+ Box::new(A(*b"foo"))
+}
+
+impl std::ops::Add<i32> for A<[u8]> {
+ type Output = ();
+ fn add(self, _rhs: i32) -> Self::Output {}
+}
+
+fn main() {
+ udrop::<[u8]>(foo()[..]);
+ //~^ERROR cannot move out of type `[u8]`, a non-copy slice
+}
diff --git a/tests/ui/unsized-locals/unsized-exprs2.stderr b/tests/ui/unsized-locals/unsized-exprs2.stderr
new file mode 100644
index 000000000..88269f237
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-exprs2.stderr
@@ -0,0 +1,12 @@
+error[E0508]: cannot move out of type `[u8]`, a non-copy slice
+ --> $DIR/unsized-exprs2.rs:22:5
+ |
+LL | udrop::<[u8]>(foo()[..]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | cannot move out of here
+ | move occurs because value has type `[u8]`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0508`.
diff --git a/tests/ui/unsized-locals/unsized-exprs3.rs b/tests/ui/unsized-locals/unsized-exprs3.rs
new file mode 100644
index 000000000..2133b01e0
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-exprs3.rs
@@ -0,0 +1,10 @@
+// aux-build:ufuncs.rs
+
+extern crate ufuncs;
+
+use ufuncs::udrop;
+
+fn main() {
+ udrop as fn([u8]);
+ //~^ERROR E0277
+}
diff --git a/tests/ui/unsized-locals/unsized-exprs3.stderr b/tests/ui/unsized-locals/unsized-exprs3.stderr
new file mode 100644
index 000000000..57d997822
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-exprs3.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/unsized-exprs3.rs:8:5
+ |
+LL | udrop as fn([u8]);
+ | ^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+ = note: all function arguments must have a statically known size
+ = help: unsized fn params are gated as an unstable feature
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/unsized-index.rs b/tests/ui/unsized-locals/unsized-index.rs
new file mode 100644
index 000000000..e8782e894
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-index.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+#![feature(unsized_fn_params)]
+
+use std::ops;
+use std::ops::Index;
+
+pub struct A;
+
+impl ops::Index<str> for A {
+ type Output = ();
+ fn index(&self, _: str) -> &Self::Output {
+ &()
+ }
+}
+
+impl ops::IndexMut<str> for A {
+ fn index_mut(&mut self, _: str) -> &mut Self::Output {
+ panic!()
+ }
+}
+
+fn main() {
+ let a = A {};
+ let s = String::new().into_boxed_str();
+ assert_eq!(&(), a.index(*s));
+}
diff --git a/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs b/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs
new file mode 100644
index 000000000..15263954c
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs
@@ -0,0 +1,15 @@
+#![feature(box_patterns)]
+#![feature(unsized_fn_params)]
+
+#[allow(dead_code)]
+fn f1(box box _b: Box<Box<[u8]>>) {}
+//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
+
+fn f2((_x, _y): (i32, [i32])) {}
+//~^ ERROR: the size for values of type `[i32]` cannot be known at compilation time [E0277]
+
+fn main() {
+ let foo: Box<[u8]> = Box::new(*b"foo");
+ let _foo: [u8] = *foo;
+ //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
+}
diff --git a/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr b/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr
new file mode 100644
index 000000000..ace5a8718
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr
@@ -0,0 +1,37 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/unsized-locals-using-unsized-fn-params.rs:5:15
+ |
+LL | fn f1(box box _b: Box<Box<[u8]>>) {}
+ | ^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+ = note: all local variables must have a statically known size
+ = help: unsized locals are gated as an unstable feature
+
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/unsized-locals-using-unsized-fn-params.rs:8:12
+ |
+LL | fn f2((_x, _y): (i32, [i32])) {}
+ | ^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[i32]`
+ = note: all local variables must have a statically known size
+ = help: unsized locals are gated as an unstable feature
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/unsized-locals-using-unsized-fn-params.rs:13:9
+ |
+LL | let _foo: [u8] = *foo;
+ | ^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+ = note: all local variables must have a statically known size
+ = help: unsized locals are gated as an unstable feature
+help: consider borrowing here
+ |
+LL | let _foo: &[u8] = *foo;
+ | +
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/unsized-parameters.rs b/tests/ui/unsized-locals/unsized-parameters.rs
new file mode 100644
index 000000000..a1b772a7e
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-parameters.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(unsized_fn_params)]
+
+pub fn f0(_f: dyn FnOnce()) {}
+pub fn f1(_s: str) {}
+pub fn f2(_x: i32, _y: [i32]) {}
+
+fn main() {
+ let foo = "foo".to_string().into_boxed_str();
+ f1(*foo);
+}