diff options
Diffstat (limited to 'src/test/ui/unsized-locals')
32 files changed, 769 insertions, 0 deletions
diff --git a/src/test/ui/unsized-locals/autoderef.rs b/src/test/ui/unsized-locals/autoderef.rs new file mode 100644 index 000000000..5dd5898c1 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/auxiliary/ufuncs.rs b/src/test/ui/unsized-locals/auxiliary/ufuncs.rs new file mode 100644 index 000000000..5954abf3a --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/borrow-after-move.rs b/src/test/ui/unsized-locals/borrow-after-move.rs new file mode 100644 index 000000000..ad73b720f --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/borrow-after-move.stderr b/src/test/ui/unsized-locals/borrow-after-move.stderr new file mode 100644 index 000000000..4f2bc06d4 --- /dev/null +++ b/src/test/ui/unsized-locals/borrow-after-move.stderr @@ -0,0 +1,72 @@ +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: `#[warn(incomplete_features)]` on by default + = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + +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 + +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: this function 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 + +error: aborting due to 5 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/unsized-locals/box-fnonce.rs b/src/test/ui/unsized-locals/box-fnonce.rs new file mode 100644 index 000000000..8b2f9b4c9 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/by-value-trait-object-safety-rpass.rs b/src/test/ui/unsized-locals/by-value-trait-object-safety-rpass.rs new file mode 100644 index 000000000..b9881defa --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs b/src/test/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs new file mode 100644 index 000000000..957991f85 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/by-value-trait-object-safety.rs b/src/test/ui/unsized-locals/by-value-trait-object-safety.rs new file mode 100644 index 000000000..d0ba6944a --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr new file mode 100644 index 000000000..59d91bc0c --- /dev/null +++ b/src/test/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: `#[warn(incomplete_features)]` on by default + = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + +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/src/test/ui/unsized-locals/double-move.rs b/src/test/ui/unsized-locals/double-move.rs new file mode 100644 index 000000000..9e46ef9be --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/double-move.stderr b/src/test/ui/unsized-locals/double-move.stderr new file mode 100644 index 000000000..4bb2ad88f --- /dev/null +++ b/src/test/ui/unsized-locals/double-move.stderr @@ -0,0 +1,78 @@ +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: `#[warn(incomplete_features)]` on by default + = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + +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 + +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: this function 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/src/test/ui/unsized-locals/issue-30276-feature-flagged.rs b/src/test/ui/unsized-locals/issue-30276-feature-flagged.rs new file mode 100644 index 000000000..635d34f82 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr b/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr new file mode 100644 index 000000000..0f0ff5793 --- /dev/null +++ b/src/test/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: `#[warn(incomplete_features)]` on by default + = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + +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/src/test/ui/unsized-locals/issue-30276.rs b/src/test/ui/unsized-locals/issue-30276.rs new file mode 100644 index 000000000..9c4bf062a --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/issue-30276.stderr b/src/test/ui/unsized-locals/issue-30276.stderr new file mode 100644 index 000000000..8cccbd792 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/issue-50940-with-feature.rs b/src/test/ui/unsized-locals/issue-50940-with-feature.rs new file mode 100644 index 000000000..63b0e830b --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/issue-50940-with-feature.stderr b/src/test/ui/unsized-locals/issue-50940-with-feature.stderr new file mode 100644 index 000000000..4523d41b6 --- /dev/null +++ b/src/test/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: `#[warn(incomplete_features)]` on by default + = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + +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/src/test/ui/unsized-locals/issue-50940.rs b/src/test/ui/unsized-locals/issue-50940.rs new file mode 100644 index 000000000..7ba809b7e --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/issue-50940.stderr b/src/test/ui/unsized-locals/issue-50940.stderr new file mode 100644 index 000000000..8f09b460e --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/reference-unsized-locals.rs b/src/test/ui/unsized-locals/reference-unsized-locals.rs new file mode 100644 index 000000000..4e887f327 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/simple-unsized-locals.rs b/src/test/ui/unsized-locals/simple-unsized-locals.rs new file mode 100644 index 000000000..02b7c299a --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-exprs-rpass.rs b/src/test/ui/unsized-locals/unsized-exprs-rpass.rs new file mode 100644 index 000000000..175b02fcb --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-exprs.rs b/src/test/ui/unsized-locals/unsized-exprs.rs new file mode 100644 index 000000000..1729b9ffa --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-exprs.stderr b/src/test/ui/unsized-locals/unsized-exprs.stderr new file mode 100644 index 000000000..6960255d9 --- /dev/null +++ b/src/test/ui/unsized-locals/unsized-exprs.stderr @@ -0,0 +1,43 @@ +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 + | | + | required by a bound introduced by this call + | + = 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/src/test/ui/unsized-locals/unsized-exprs2.rs b/src/test/ui/unsized-locals/unsized-exprs2.rs new file mode 100644 index 000000000..127d8717e --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-exprs2.stderr b/src/test/ui/unsized-locals/unsized-exprs2.stderr new file mode 100644 index 000000000..88269f237 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-exprs3.rs b/src/test/ui/unsized-locals/unsized-exprs3.rs new file mode 100644 index 000000000..2133b01e0 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-exprs3.stderr b/src/test/ui/unsized-locals/unsized-exprs3.stderr new file mode 100644 index 000000000..57d997822 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-index.rs b/src/test/ui/unsized-locals/unsized-index.rs new file mode 100644 index 000000000..e8782e894 --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs b/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs new file mode 100644 index 000000000..15263954c --- /dev/null +++ b/src/test/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/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr b/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr new file mode 100644 index 000000000..da7702667 --- /dev/null +++ b/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr @@ -0,0 +1,33 @@ +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 + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized-locals/unsized-parameters.rs b/src/test/ui/unsized-locals/unsized-parameters.rs new file mode 100644 index 000000000..a1b772a7e --- /dev/null +++ b/src/test/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); +} |