From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/unsized/box-instead-of-dyn-fn.rs | 15 + src/test/ui/unsized/box-instead-of-dyn-fn.stderr | 42 +++ src/test/ui/unsized/issue-30355.rs | 9 + src/test/ui/unsized/issue-30355.stderr | 13 + src/test/ui/unsized/issue-40231-1.rs | 54 +++ src/test/ui/unsized/issue-40231-2.rs | 54 +++ src/test/ui/unsized/issue-71659.rs | 32 ++ src/test/ui/unsized/issue-71659.stderr | 18 + src/test/ui/unsized/issue-75707.rs | 17 + src/test/ui/unsized/issue-75707.stderr | 15 + src/test/ui/unsized/issue-91801.rs | 19 + src/test/ui/unsized/issue-91801.stderr | 15 + src/test/ui/unsized/issue-91803.rs | 8 + src/test/ui/unsized/issue-91803.stderr | 15 + src/test/ui/unsized/issue-97732.rs | 28 ++ src/test/ui/unsized/maybe-bounds-where-cpass.rs | 9 + src/test/ui/unsized/maybe-bounds-where.rs | 28 ++ src/test/ui/unsized/maybe-bounds-where.stderr | 51 +++ .../unsized/param-mentioned-by-different-field.rs | 10 + .../param-mentioned-by-different-field.stderr | 14 + .../ui/unsized/return-unsized-from-trait-method.rs | 14 + .../return-unsized-from-trait-method.stderr | 9 + src/test/ui/unsized/unchanged-param.rs | 11 + src/test/ui/unsized/unsized-bare-typaram.rs | 4 + src/test/ui/unsized/unsized-bare-typaram.stderr | 22 ++ src/test/ui/unsized/unsized-enum.rs | 11 + src/test/ui/unsized/unsized-enum.stderr | 29 ++ src/test/ui/unsized/unsized-enum2.rs | 74 ++++ src/test/ui/unsized/unsized-enum2.stderr | 411 +++++++++++++++++++++ src/test/ui/unsized/unsized-fn-arg.fixed | 6 + src/test/ui/unsized/unsized-fn-arg.rs | 6 + src/test/ui/unsized/unsized-fn-arg.stderr | 22 ++ src/test/ui/unsized/unsized-fn-param.rs | 20 + src/test/ui/unsized/unsized-fn-param.stderr | 63 ++++ .../ui/unsized/unsized-inherent-impl-self-type.rs | 11 + .../unsized/unsized-inherent-impl-self-type.stderr | 29 ++ src/test/ui/unsized/unsized-struct.rs | 18 + src/test/ui/unsized/unsized-struct.stderr | 53 +++ .../ui/unsized/unsized-trait-impl-self-type.rs | 14 + .../ui/unsized/unsized-trait-impl-self-type.stderr | 29 ++ .../ui/unsized/unsized-trait-impl-trait-arg.rs | 12 + .../ui/unsized/unsized-trait-impl-trait-arg.stderr | 26 ++ src/test/ui/unsized/unsized-tuple-impls.rs | 21 ++ src/test/ui/unsized/unsized.rs | 25 ++ src/test/ui/unsized/unsized2.rs | 96 +++++ src/test/ui/unsized/unsized3-rpass.rs | 93 +++++ src/test/ui/unsized/unsized3.rs | 50 +++ src/test/ui/unsized/unsized3.stderr | 159 ++++++++ src/test/ui/unsized/unsized5.rs | 34 ++ src/test/ui/unsized/unsized5.stderr | 136 +++++++ src/test/ui/unsized/unsized6.rs | 44 +++ src/test/ui/unsized/unsized6.stderr | 222 +++++++++++ src/test/ui/unsized/unsized7.rs | 16 + src/test/ui/unsized/unsized7.stderr | 26 ++ 54 files changed, 2282 insertions(+) create mode 100644 src/test/ui/unsized/box-instead-of-dyn-fn.rs create mode 100644 src/test/ui/unsized/box-instead-of-dyn-fn.stderr create mode 100644 src/test/ui/unsized/issue-30355.rs create mode 100644 src/test/ui/unsized/issue-30355.stderr create mode 100644 src/test/ui/unsized/issue-40231-1.rs create mode 100644 src/test/ui/unsized/issue-40231-2.rs create mode 100644 src/test/ui/unsized/issue-71659.rs create mode 100644 src/test/ui/unsized/issue-71659.stderr create mode 100644 src/test/ui/unsized/issue-75707.rs create mode 100644 src/test/ui/unsized/issue-75707.stderr create mode 100644 src/test/ui/unsized/issue-91801.rs create mode 100644 src/test/ui/unsized/issue-91801.stderr create mode 100644 src/test/ui/unsized/issue-91803.rs create mode 100644 src/test/ui/unsized/issue-91803.stderr create mode 100644 src/test/ui/unsized/issue-97732.rs create mode 100644 src/test/ui/unsized/maybe-bounds-where-cpass.rs create mode 100644 src/test/ui/unsized/maybe-bounds-where.rs create mode 100644 src/test/ui/unsized/maybe-bounds-where.stderr create mode 100644 src/test/ui/unsized/param-mentioned-by-different-field.rs create mode 100644 src/test/ui/unsized/param-mentioned-by-different-field.stderr create mode 100644 src/test/ui/unsized/return-unsized-from-trait-method.rs create mode 100644 src/test/ui/unsized/return-unsized-from-trait-method.stderr create mode 100644 src/test/ui/unsized/unchanged-param.rs create mode 100644 src/test/ui/unsized/unsized-bare-typaram.rs create mode 100644 src/test/ui/unsized/unsized-bare-typaram.stderr create mode 100644 src/test/ui/unsized/unsized-enum.rs create mode 100644 src/test/ui/unsized/unsized-enum.stderr create mode 100644 src/test/ui/unsized/unsized-enum2.rs create mode 100644 src/test/ui/unsized/unsized-enum2.stderr create mode 100644 src/test/ui/unsized/unsized-fn-arg.fixed create mode 100644 src/test/ui/unsized/unsized-fn-arg.rs create mode 100644 src/test/ui/unsized/unsized-fn-arg.stderr create mode 100644 src/test/ui/unsized/unsized-fn-param.rs create mode 100644 src/test/ui/unsized/unsized-fn-param.stderr create mode 100644 src/test/ui/unsized/unsized-inherent-impl-self-type.rs create mode 100644 src/test/ui/unsized/unsized-inherent-impl-self-type.stderr create mode 100644 src/test/ui/unsized/unsized-struct.rs create mode 100644 src/test/ui/unsized/unsized-struct.stderr create mode 100644 src/test/ui/unsized/unsized-trait-impl-self-type.rs create mode 100644 src/test/ui/unsized/unsized-trait-impl-self-type.stderr create mode 100644 src/test/ui/unsized/unsized-trait-impl-trait-arg.rs create mode 100644 src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr create mode 100644 src/test/ui/unsized/unsized-tuple-impls.rs create mode 100644 src/test/ui/unsized/unsized.rs create mode 100644 src/test/ui/unsized/unsized2.rs create mode 100644 src/test/ui/unsized/unsized3-rpass.rs create mode 100644 src/test/ui/unsized/unsized3.rs create mode 100644 src/test/ui/unsized/unsized3.stderr create mode 100644 src/test/ui/unsized/unsized5.rs create mode 100644 src/test/ui/unsized/unsized5.stderr create mode 100644 src/test/ui/unsized/unsized6.rs create mode 100644 src/test/ui/unsized/unsized6.stderr create mode 100644 src/test/ui/unsized/unsized7.rs create mode 100644 src/test/ui/unsized/unsized7.stderr (limited to 'src/test/ui/unsized') diff --git a/src/test/ui/unsized/box-instead-of-dyn-fn.rs b/src/test/ui/unsized/box-instead-of-dyn-fn.rs new file mode 100644 index 000000000..2fa741bc1 --- /dev/null +++ b/src/test/ui/unsized/box-instead-of-dyn-fn.rs @@ -0,0 +1,15 @@ +use std::fmt::Debug; + +// Test to suggest boxing the return type, and the closure branch of the `if` + +fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a { + //~^ ERROR return type cannot have an unboxed trait object + if a % 2 == 0 { + move || println!("{a}") + } else { + Box::new(move || println!("{}", b)) + //~^ ERROR `if` and `else` have incompatible types + } +} + +fn main() {} diff --git a/src/test/ui/unsized/box-instead-of-dyn-fn.stderr b/src/test/ui/unsized/box-instead-of-dyn-fn.stderr new file mode 100644 index 000000000..c96c59afc --- /dev/null +++ b/src/test/ui/unsized/box-instead-of-dyn-fn.stderr @@ -0,0 +1,42 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/box-instead-of-dyn-fn.rs:10:9 + | +LL | / if a % 2 == 0 { +LL | | move || println!("{a}") + | | ----------------------- + | | | + | | the expected closure + | | expected because of this +LL | | } else { +LL | | Box::new(move || println!("{}", b)) + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found struct `Box` +LL | | +LL | | } + | |_____- `if` and `else` have incompatible types + | + = note: expected closure `[closure@$DIR/box-instead-of-dyn-fn.rs:8:9: 8:16]` + found struct `Box<[closure@$DIR/box-instead-of-dyn-fn.rs:10:18: 10:25]>` + +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/box-instead-of-dyn-fn.rs:5:56 + | +LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a { + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on trait objects, see + = note: if all the returned values were of the same type you could use `impl Fn() + 'a` as the return type + = note: for information on `impl Trait`, see + = note: you can create a new `enum` with a variant for each returned type +help: return a boxed trait object instead + | +LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> Box { + | ++++ + +help: ... and box this value + | +LL | Box::new(move || println!("{a}")) + | +++++++++ + + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0746. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/unsized/issue-30355.rs b/src/test/ui/unsized/issue-30355.rs new file mode 100644 index 000000000..6ff5b37f6 --- /dev/null +++ b/src/test/ui/unsized/issue-30355.rs @@ -0,0 +1,9 @@ +pub struct X([u8]); + +pub static Y: &'static X = { + const Y: &'static [u8] = b""; + &X(*Y) + //~^ ERROR E0277 +}; + +fn main() {} diff --git a/src/test/ui/unsized/issue-30355.stderr b/src/test/ui/unsized/issue-30355.stderr new file mode 100644 index 000000000..71bbdf5de --- /dev/null +++ b/src/test/ui/unsized/issue-30355.stderr @@ -0,0 +1,13 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-30355.rs:5:8 + | +LL | &X(*Y) + | ^^ 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/issue-40231-1.rs b/src/test/ui/unsized/issue-40231-1.rs new file mode 100644 index 000000000..999399ec8 --- /dev/null +++ b/src/test/ui/unsized/issue-40231-1.rs @@ -0,0 +1,54 @@ +// check-pass + +#![allow(dead_code)] + +trait Structure: Sized where E: Encoding { + type RefTarget: ?Sized; + type FfiPtr; + unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; +} + +enum Slice {} + +impl Structure for Slice where E: Encoding { + type RefTarget = [E::Unit]; + type FfiPtr = (*const E::FfiUnit, usize); + unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { + panic!() + } +} + +trait Encoding { + type Unit: Unit; + type FfiUnit; +} + +trait Unit {} + +enum Utf16 {} + +impl Encoding for Utf16 { + type Unit = Utf16Unit; + type FfiUnit = u16; +} + +struct Utf16Unit(pub u16); + +impl Unit for Utf16Unit {} + +type SUtf16Str = SeStr; + +struct SeStr where S: Structure, E: Encoding { + _data: S::RefTarget, +} + +impl SeStr where S: Structure, E: Encoding { + pub unsafe fn from_ptr<'a>(_ptr: S::FfiPtr) -> Option<&'a Self> { + panic!() + } +} + +fn main() { + const TEXT_U16: &'static [u16] = &[]; + let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; +} diff --git a/src/test/ui/unsized/issue-40231-2.rs b/src/test/ui/unsized/issue-40231-2.rs new file mode 100644 index 000000000..780433b28 --- /dev/null +++ b/src/test/ui/unsized/issue-40231-2.rs @@ -0,0 +1,54 @@ +// check-pass + +#![allow(dead_code)] + +trait Structure: Sized where E: Encoding { + type RefTarget: ?Sized; + type FfiPtr; + unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; +} + +enum Slice {} + +impl Structure for Slice where E: Encoding { + type RefTarget = [E::Unit]; + type FfiPtr = (*const E::FfiUnit, usize); + unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { + panic!() + } +} + +trait Encoding { + type Unit: Unit; + type FfiUnit; +} + +trait Unit {} + +enum Utf16 {} + +impl Encoding for Utf16 { + type Unit = Utf16Unit; + type FfiUnit = u16; +} + +struct Utf16Unit(pub u16); + +impl Unit for Utf16Unit {} + +struct SUtf16Str { + _data: >::RefTarget, +} + +impl SUtf16Str { + pub unsafe fn from_ptr<'a>(ptr: >::FfiPtr) + -> Option<&'a Self> { + std::mem::transmute::::Unit]>, _>( + >::borrow_from_ffi_ptr(ptr)) + } +} + +fn main() { + const TEXT_U16: &'static [u16] = &[]; + let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; +} diff --git a/src/test/ui/unsized/issue-71659.rs b/src/test/ui/unsized/issue-71659.rs new file mode 100644 index 000000000..3524ca02b --- /dev/null +++ b/src/test/ui/unsized/issue-71659.rs @@ -0,0 +1,32 @@ +#![feature(unsize)] + +use std::marker::Unsize; + +pub trait CastTo: Unsize { + fn cast_to(&self) -> &T; +} + +impl> CastTo for U { + fn cast_to(&self) -> &T { + self + } +} + +impl Cast for T {} +pub trait Cast { + fn cast(&self) -> &T + where + Self: CastTo, + { + self + } +} + +pub trait Foo: CastTo<[i32]> {} +impl Foo for [i32; 0] {} + +fn main() { + let x: &dyn Foo = &[]; + let x = x.cast::<[i32]>(); + //~^ ERROR: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied +} diff --git a/src/test/ui/unsized/issue-71659.stderr b/src/test/ui/unsized/issue-71659.stderr new file mode 100644 index 000000000..d7b95f557 --- /dev/null +++ b/src/test/ui/unsized/issue-71659.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied + --> $DIR/issue-71659.rs:30:15 + | +LL | let x = x.cast::<[i32]>(); + | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo` + | +note: required by a bound in `Cast::cast` + --> $DIR/issue-71659.rs:19:15 + | +LL | fn cast(&self) -> &T + | ---- required by a bound in this +LL | where +LL | Self: CastTo, + | ^^^^^^^^^ required by this bound in `Cast::cast` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/issue-75707.rs b/src/test/ui/unsized/issue-75707.rs new file mode 100644 index 000000000..9f04cdbb9 --- /dev/null +++ b/src/test/ui/unsized/issue-75707.rs @@ -0,0 +1,17 @@ +pub trait Callback { + fn cb(); +} + +pub trait Processing { + type Call: Callback; +} + +fn f() { + P::Call::cb(); +} + +fn main() { + struct MyCall; + f::>(); + //~^ ERROR: the trait bound `MyCall: Callback` is not satisfied +} diff --git a/src/test/ui/unsized/issue-75707.stderr b/src/test/ui/unsized/issue-75707.stderr new file mode 100644 index 000000000..7d0a2cb85 --- /dev/null +++ b/src/test/ui/unsized/issue-75707.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `MyCall: Callback` is not satisfied + --> $DIR/issue-75707.rs:15:5 + | +LL | f::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall` + | +note: required by a bound in `f` + --> $DIR/issue-75707.rs:9:9 + | +LL | fn f() { + | ^^^^^^^^^^ required by this bound in `f` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/issue-91801.rs b/src/test/ui/unsized/issue-91801.rs new file mode 100644 index 000000000..096b1a935 --- /dev/null +++ b/src/test/ui/unsized/issue-91801.rs @@ -0,0 +1,19 @@ +pub struct Something; + +type Validator<'a> = dyn 'a + Send + Sync + Fn(&'a Something) -> Result<(), ()>; + +pub static ALL_VALIDATORS: &[(&'static str, &'static Validator)] = + &[("validate that credits and debits balance", &validate_something)]; + +fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { + //~^ ERROR return type cannot have an unboxed trait object + return Box::new(move |something: &'_ Something| -> Result<(), ()> { + first(something).or_else(|_| second(something)) + }); +} + +fn validate_something(_: &Something) -> Result<(), ()> { + Ok(()) +} + +fn main() {} diff --git a/src/test/ui/unsized/issue-91801.stderr b/src/test/ui/unsized/issue-91801.stderr new file mode 100644 index 000000000..8795aa168 --- /dev/null +++ b/src/test/ui/unsized/issue-91801.stderr @@ -0,0 +1,15 @@ +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/issue-91801.rs:8:77 + | +LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: use `impl Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a` as the return type, as all return paths are of type `Box<[closure@$DIR/issue-91801.rs:10:21: 10:70]>`, which implements `Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a` + | +LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> impl Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0746`. diff --git a/src/test/ui/unsized/issue-91803.rs b/src/test/ui/unsized/issue-91803.rs new file mode 100644 index 000000000..c74897cc4 --- /dev/null +++ b/src/test/ui/unsized/issue-91803.rs @@ -0,0 +1,8 @@ +trait Foo<'a> {} + +fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> { + //~^ ERROR return type cannot have an unboxed trait object + return Box::new(panic!()); +} + +fn main() {} diff --git a/src/test/ui/unsized/issue-91803.stderr b/src/test/ui/unsized/issue-91803.stderr new file mode 100644 index 000000000..2dad9e892 --- /dev/null +++ b/src/test/ui/unsized/issue-91803.stderr @@ -0,0 +1,15 @@ +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/issue-91803.rs:3:43 + | +LL | fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> { + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: use `impl Foo<'a>` as the return type, as all return paths are of type `Box<_>`, which implements `Foo<'a>` + | +LL | fn or<'a>(first: &'static dyn Foo<'a>) -> impl Foo<'a> { + | ~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0746`. diff --git a/src/test/ui/unsized/issue-97732.rs b/src/test/ui/unsized/issue-97732.rs new file mode 100644 index 000000000..72f765033 --- /dev/null +++ b/src/test/ui/unsized/issue-97732.rs @@ -0,0 +1,28 @@ +// check-pass + +#![feature(coerce_unsized)] + +// Ensure that unsizing structs that contain ZSTs at non-zero offsets don't ICE + +use std::ops::CoerceUnsized; + +#[repr(C)] +pub struct BoxWithZstTail(Box, ()); + +impl CoerceUnsized> for BoxWithZstTail where + Box: CoerceUnsized> +{ +} + +pub fn noop_dyn_upcast_with_zst_tail( + b: BoxWithZstTail, +) -> BoxWithZstTail { + b +} + +fn main() { + let original = "foo"; + let boxed = BoxWithZstTail(Box::new(original) as Box, ()); + let noop_upcasted = noop_dyn_upcast_with_zst_tail(boxed); + assert_eq!(original, noop_upcasted.0.to_string()); +} diff --git a/src/test/ui/unsized/maybe-bounds-where-cpass.rs b/src/test/ui/unsized/maybe-bounds-where-cpass.rs new file mode 100644 index 000000000..0e018cdab --- /dev/null +++ b/src/test/ui/unsized/maybe-bounds-where-cpass.rs @@ -0,0 +1,9 @@ +// check-pass + +struct S(*const T) where T: ?Sized; + + +fn main() { + let u = vec![1, 2, 3]; + let _s: S<[u8]> = S(&u[..]); +} diff --git a/src/test/ui/unsized/maybe-bounds-where.rs b/src/test/ui/unsized/maybe-bounds-where.rs new file mode 100644 index 000000000..d7af0c424 --- /dev/null +++ b/src/test/ui/unsized/maybe-bounds-where.rs @@ -0,0 +1,28 @@ +struct S1(T) where (T): ?Sized; +//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared + +struct S2(T) where u8: ?Sized; +//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared + +struct S3(T) where &'static T: ?Sized; +//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared + +trait Trait<'a> {} + +struct S4(T) where for<'a> T: ?Trait<'a>; +//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared +//~| WARN default bound relaxed for a type parameter + +struct S5(*const T) where T: ?Trait<'static> + ?Sized; +//~^ ERROR type parameter has more than one relaxed default bound +//~| WARN default bound relaxed for a type parameter + +impl S1 { + fn f() where T: ?Sized {} + //~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared +} + +fn main() { + let u = vec![1, 2, 3]; + let _s: S5<[u8]> = S5(&u[..]); // OK +} diff --git a/src/test/ui/unsized/maybe-bounds-where.stderr b/src/test/ui/unsized/maybe-bounds-where.stderr new file mode 100644 index 000000000..39bc1b88e --- /dev/null +++ b/src/test/ui/unsized/maybe-bounds-where.stderr @@ -0,0 +1,51 @@ +error: `?Trait` bounds are only permitted at the point where a type parameter is declared + --> $DIR/maybe-bounds-where.rs:1:28 + | +LL | struct S1(T) where (T): ?Sized; + | ^^^^^^ + +error: `?Trait` bounds are only permitted at the point where a type parameter is declared + --> $DIR/maybe-bounds-where.rs:4:27 + | +LL | struct S2(T) where u8: ?Sized; + | ^^^^^^ + +error: `?Trait` bounds are only permitted at the point where a type parameter is declared + --> $DIR/maybe-bounds-where.rs:7:35 + | +LL | struct S3(T) where &'static T: ?Sized; + | ^^^^^^ + +error: `?Trait` bounds are only permitted at the point where a type parameter is declared + --> $DIR/maybe-bounds-where.rs:12:34 + | +LL | struct S4(T) where for<'a> T: ?Trait<'a>; + | ^^^^^^^^^^ + +error: `?Trait` bounds are only permitted at the point where a type parameter is declared + --> $DIR/maybe-bounds-where.rs:21:21 + | +LL | fn f() where T: ?Sized {} + | ^^^^^^ + +warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported + --> $DIR/maybe-bounds-where.rs:12:11 + | +LL | struct S4(T) where for<'a> T: ?Trait<'a>; + | ^ + +error[E0203]: type parameter has more than one relaxed default bound, only one is supported + --> $DIR/maybe-bounds-where.rs:16:11 + | +LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized; + | ^ + +warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported + --> $DIR/maybe-bounds-where.rs:16:11 + | +LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized; + | ^ + +error: aborting due to 6 previous errors; 2 warnings emitted + +For more information about this error, try `rustc --explain E0203`. diff --git a/src/test/ui/unsized/param-mentioned-by-different-field.rs b/src/test/ui/unsized/param-mentioned-by-different-field.rs new file mode 100644 index 000000000..cda94b306 --- /dev/null +++ b/src/test/ui/unsized/param-mentioned-by-different-field.rs @@ -0,0 +1,10 @@ +// We must not allow this with our current setup as `T` +// is mentioned both in the tail of `Foo` and by another +// field. +struct Foo(Box, T); + +fn main() { + let x: Foo<[u8; 1]> = Foo(Box::new([2]), [3]); + let y: &Foo<[u8]> = &x; //~ ERROR mismatched types + assert_eq!(y.0.len(), 1); +} diff --git a/src/test/ui/unsized/param-mentioned-by-different-field.stderr b/src/test/ui/unsized/param-mentioned-by-different-field.stderr new file mode 100644 index 000000000..d18fa6456 --- /dev/null +++ b/src/test/ui/unsized/param-mentioned-by-different-field.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/param-mentioned-by-different-field.rs:8:25 + | +LL | let y: &Foo<[u8]> = &x; + | ---------- ^^ expected slice `[u8]`, found array `[u8; 1]` + | | + | expected due to this + | + = note: expected reference `&Foo<[u8]>` + found reference `&Foo<[u8; 1]>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/unsized/return-unsized-from-trait-method.rs b/src/test/ui/unsized/return-unsized-from-trait-method.rs new file mode 100644 index 000000000..f053f4b0a --- /dev/null +++ b/src/test/ui/unsized/return-unsized-from-trait-method.rs @@ -0,0 +1,14 @@ +// regression test for #26376 + +trait Foo { + fn foo(&self) -> [u8]; +} + +fn foo(f: Option<&dyn Foo>) { + if let Some(f) = f { + let _ = f.foo(); + //~^ ERROR cannot move a value of type `[u8]` + } +} + +fn main() { foo(None) } diff --git a/src/test/ui/unsized/return-unsized-from-trait-method.stderr b/src/test/ui/unsized/return-unsized-from-trait-method.stderr new file mode 100644 index 000000000..671d40993 --- /dev/null +++ b/src/test/ui/unsized/return-unsized-from-trait-method.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type `[u8]` + --> $DIR/return-unsized-from-trait-method.rs:9:17 + | +LL | let _ = f.foo(); + | ^^^^^^^ the size of `[u8]` cannot be statically determined + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0161`. diff --git a/src/test/ui/unsized/unchanged-param.rs b/src/test/ui/unsized/unchanged-param.rs new file mode 100644 index 000000000..6bdc89310 --- /dev/null +++ b/src/test/ui/unsized/unchanged-param.rs @@ -0,0 +1,11 @@ +// run-pass +// Test that we allow unsizing even if there is an unchanged param in the +// field getting unsized. +struct A(#[allow(unused_tuple_struct_fields)] T, B); +struct B(#[allow(unused_tuple_struct_fields)] T, U); + +fn main() { + let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1])); + let y: &A<[u32; 1], [u32]> = &x; + assert_eq!(y.1.1.len(), 1); +} diff --git a/src/test/ui/unsized/unsized-bare-typaram.rs b/src/test/ui/unsized/unsized-bare-typaram.rs new file mode 100644 index 000000000..e611da915 --- /dev/null +++ b/src/test/ui/unsized/unsized-bare-typaram.rs @@ -0,0 +1,4 @@ +fn bar() { } +fn foo() { bar::() } +//~^ ERROR the size for values of type +fn main() { } diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr new file mode 100644 index 000000000..1eff14be8 --- /dev/null +++ b/src/test/ui/unsized/unsized-bare-typaram.stderr @@ -0,0 +1,22 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/unsized-bare-typaram.rs:2:29 + | +LL | fn foo() { bar::() } + | - ^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required by a bound in `bar` + --> $DIR/unsized-bare-typaram.rs:1:8 + | +LL | fn bar() { } + | ^ required by this bound in `bar` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn foo() { bar::() } +LL + fn foo() { bar::() } + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-enum.rs b/src/test/ui/unsized/unsized-enum.rs new file mode 100644 index 000000000..02ad1c878 --- /dev/null +++ b/src/test/ui/unsized/unsized-enum.rs @@ -0,0 +1,11 @@ +fn is_sized() { } +fn not_sized() { } + +enum Foo { FooSome(U), FooNone } +fn foo1() { not_sized::>() } // Hunky dory. +fn foo2() { not_sized::>() } +//~^ ERROR the size for values of type +// +// Not OK: `T` is not sized. + +fn main() { } diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr new file mode 100644 index 000000000..5f2e22430 --- /dev/null +++ b/src/test/ui/unsized/unsized-enum.stderr @@ -0,0 +1,29 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/unsized-enum.rs:6:36 + | +LL | fn foo2() { not_sized::>() } + | - ^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required by a bound in `Foo` + --> $DIR/unsized-enum.rs:4:10 + | +LL | enum Foo { FooSome(U), FooNone } + | ^ required by this bound in `Foo` +help: you could relax the implicit `Sized` bound on `U` if it were used through indirection like `&U` or `Box` + --> $DIR/unsized-enum.rs:4:10 + | +LL | enum Foo { FooSome(U), FooNone } + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `U: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn foo2() { not_sized::>() } +LL + fn foo2() { not_sized::>() } + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-enum2.rs b/src/test/ui/unsized/unsized-enum2.rs new file mode 100644 index 000000000..d589f5ae5 --- /dev/null +++ b/src/test/ui/unsized/unsized-enum2.rs @@ -0,0 +1,74 @@ +use std::ops::Deref; + +// Due to aggressive error message deduplication, we require 20 *different* +// unsized types (even Path and [u8] are considered the "same"). + +trait Foo {} +trait Bar {} +trait FooBar {} +trait BarFoo {} + +trait PathHelper1 {} +trait PathHelper2 {} +trait PathHelper3 {} +trait PathHelper4 {} + +struct Path1(dyn PathHelper1); +struct Path2(dyn PathHelper2); +struct Path3(dyn PathHelper3); +struct Path4(dyn PathHelper4); + +enum E { + // parameter + VA(W), + //~^ ERROR the size for values of type + VB{x: X}, + //~^ ERROR the size for values of type + VC(isize, Y), + //~^ ERROR the size for values of type + VD{u: isize, x: Z}, + //~^ ERROR the size for values of type + + // slice / str + VE([u8]), + //~^ ERROR the size for values of type + VF{x: str}, + //~^ ERROR the size for values of type + VG(isize, [f32]), + //~^ ERROR the size for values of type + VH{u: isize, x: [u32]}, + //~^ ERROR the size for values of type + + // unsized struct + VI(Path1), + //~^ ERROR the size for values of type + VJ{x: Path2}, + //~^ ERROR the size for values of type + VK(isize, Path3), + //~^ ERROR the size for values of type + VL{u: isize, x: Path4}, + //~^ ERROR the size for values of type + + // plain trait + VM(dyn Foo), + //~^ ERROR the size for values of type + VN{x: dyn Bar}, + //~^ ERROR the size for values of type + VO(isize, dyn FooBar), + //~^ ERROR the size for values of type + VP{u: isize, x: dyn BarFoo}, + //~^ ERROR the size for values of type + + // projected + VQ(<&'static [i8] as Deref>::Target), + //~^ ERROR the size for values of type + VR{x: <&'static [char] as Deref>::Target}, + //~^ ERROR the size for values of type + VS(isize, <&'static [f64] as Deref>::Target), + //~^ ERROR the size for values of type + VT{u: isize, x: <&'static [i32] as Deref>::Target}, + //~^ ERROR the size for values of type +} + + +fn main() { } diff --git a/src/test/ui/unsized/unsized-enum2.stderr b/src/test/ui/unsized/unsized-enum2.stderr new file mode 100644 index 000000000..00b80327c --- /dev/null +++ b/src/test/ui/unsized/unsized-enum2.stderr @@ -0,0 +1,411 @@ +error[E0277]: the size for values of type `W` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:23:8 + | +LL | enum E { + | - this type parameter needs to be `std::marker::Sized` +LL | // parameter +LL | VA(W), + | ^ doesn't have a size known at compile-time + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - enum E { +LL + enum E { + | +help: borrowed types always have a statically known size + | +LL | VA(&W), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VA(Box), + | ++++ + + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:25:11 + | +LL | enum E { + | - this type parameter needs to be `std::marker::Sized` +... +LL | VB{x: X}, + | ^ doesn't have a size known at compile-time + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - enum E { +LL + enum E { + | +help: borrowed types always have a statically known size + | +LL | VB{x: &X}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VB{x: Box}, + | ++++ + + +error[E0277]: the size for values of type `Y` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:27:15 + | +LL | enum E { + | - this type parameter needs to be `std::marker::Sized` +... +LL | VC(isize, Y), + | ^ doesn't have a size known at compile-time + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - enum E { +LL + enum E { + | +help: borrowed types always have a statically known size + | +LL | VC(isize, &Y), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VC(isize, Box), + | ++++ + + +error[E0277]: the size for values of type `Z` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:29:21 + | +LL | enum E { + | - this type parameter needs to be `std::marker::Sized` +... +LL | VD{u: isize, x: Z}, + | ^ doesn't have a size known at compile-time + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - enum E { +LL + enum E { + | +help: borrowed types always have a statically known size + | +LL | VD{u: isize, x: &Z}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VD{u: isize, x: Box}, + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:33:8 + | +LL | VE([u8]), + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VE(&[u8]), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VE(Box<[u8]>), + | ++++ + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:35:11 + | +LL | VF{x: str}, + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VF{x: &str}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VF{x: Box}, + | ++++ + + +error[E0277]: the size for values of type `[f32]` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:37:15 + | +LL | VG(isize, [f32]), + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[f32]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VG(isize, &[f32]), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VG(isize, Box<[f32]>), + | ++++ + + +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:39:21 + | +LL | VH{u: isize, x: [u32]}, + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VH{u: isize, x: &[u32]}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VH{u: isize, x: Box<[u32]>}, + | ++++ + + +error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:53:8 + | +LL | VM(dyn Foo), + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VM(&dyn Foo), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VM(Box), + | ++++ + + +error[E0277]: the size for values of type `(dyn Bar + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:55:11 + | +LL | VN{x: dyn Bar}, + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Bar + 'static)` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VN{x: &dyn Bar}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VN{x: Box}, + | ++++ + + +error[E0277]: the size for values of type `(dyn FooBar + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:57:15 + | +LL | VO(isize, dyn FooBar), + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn FooBar + 'static)` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VO(isize, &dyn FooBar), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VO(isize, Box), + | ++++ + + +error[E0277]: the size for values of type `(dyn BarFoo + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:59:21 + | +LL | VP{u: isize, x: dyn BarFoo}, + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn BarFoo + 'static)` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VP{u: isize, x: &dyn BarFoo}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VP{u: isize, x: Box}, + | ++++ + + +error[E0277]: the size for values of type `[i8]` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:63:8 + | +LL | VQ(<&'static [i8] as Deref>::Target), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VQ(&<&'static [i8] as Deref>::Target), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VQ(Box<<&'static [i8] as Deref>::Target>), + | ++++ + + +error[E0277]: the size for values of type `[char]` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:65:11 + | +LL | VR{x: <&'static [char] as Deref>::Target}, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[char]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VR{x: &<&'static [char] as Deref>::Target}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VR{x: Box<<&'static [char] as Deref>::Target>}, + | ++++ + + +error[E0277]: the size for values of type `[f64]` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:67:15 + | +LL | VS(isize, <&'static [f64] as Deref>::Target), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[f64]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VS(isize, &<&'static [f64] as Deref>::Target), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VS(isize, Box<<&'static [f64] as Deref>::Target>), + | ++++ + + +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:69:21 + | +LL | VT{u: isize, x: <&'static [i32] as Deref>::Target}, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i32]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VT{u: isize, x: &<&'static [i32] as Deref>::Target}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VT{u: isize, x: Box<<&'static [i32] as Deref>::Target>}, + | ++++ + + +error[E0277]: the size for values of type `(dyn PathHelper1 + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:43:8 + | +LL | VI(Path1), + | ^^^^^ doesn't have a size known at compile-time + | + = help: within `Path1`, the trait `Sized` is not implemented for `(dyn PathHelper1 + 'static)` +note: required because it appears within the type `Path1` + --> $DIR/unsized-enum2.rs:16:8 + | +LL | struct Path1(dyn PathHelper1); + | ^^^^^ + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VI(&Path1), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VI(Box), + | ++++ + + +error[E0277]: the size for values of type `(dyn PathHelper2 + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:45:11 + | +LL | VJ{x: Path2}, + | ^^^^^ doesn't have a size known at compile-time + | + = help: within `Path2`, the trait `Sized` is not implemented for `(dyn PathHelper2 + 'static)` +note: required because it appears within the type `Path2` + --> $DIR/unsized-enum2.rs:17:8 + | +LL | struct Path2(dyn PathHelper2); + | ^^^^^ + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VJ{x: &Path2}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VJ{x: Box}, + | ++++ + + +error[E0277]: the size for values of type `(dyn PathHelper3 + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:47:15 + | +LL | VK(isize, Path3), + | ^^^^^ doesn't have a size known at compile-time + | + = help: within `Path3`, the trait `Sized` is not implemented for `(dyn PathHelper3 + 'static)` +note: required because it appears within the type `Path3` + --> $DIR/unsized-enum2.rs:18:8 + | +LL | struct Path3(dyn PathHelper3); + | ^^^^^ + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VK(isize, &Path3), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VK(isize, Box), + | ++++ + + +error[E0277]: the size for values of type `(dyn PathHelper4 + 'static)` cannot be known at compilation time + --> $DIR/unsized-enum2.rs:49:21 + | +LL | VL{u: isize, x: Path4}, + | ^^^^^ doesn't have a size known at compile-time + | + = help: within `Path4`, the trait `Sized` is not implemented for `(dyn PathHelper4 + 'static)` +note: required because it appears within the type `Path4` + --> $DIR/unsized-enum2.rs:19:8 + | +LL | struct Path4(dyn PathHelper4); + | ^^^^^ + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | VL{u: isize, x: &Path4}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | VL{u: isize, x: Box}, + | ++++ + + +error: aborting due to 20 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-fn-arg.fixed b/src/test/ui/unsized/unsized-fn-arg.fixed new file mode 100644 index 000000000..fd9b159a4 --- /dev/null +++ b/src/test/ui/unsized/unsized-fn-arg.fixed @@ -0,0 +1,6 @@ +// run-rustfix +#![crate_type="lib"] +#![allow(unused)] + +fn f(t: &T) {} +//~^ ERROR the size for values of type `T` cannot be known at compilation time diff --git a/src/test/ui/unsized/unsized-fn-arg.rs b/src/test/ui/unsized/unsized-fn-arg.rs new file mode 100644 index 000000000..9fc08bd6d --- /dev/null +++ b/src/test/ui/unsized/unsized-fn-arg.rs @@ -0,0 +1,6 @@ +// run-rustfix +#![crate_type="lib"] +#![allow(unused)] + +fn f(t: T) {} +//~^ ERROR the size for values of type `T` cannot be known at compilation time diff --git a/src/test/ui/unsized/unsized-fn-arg.stderr b/src/test/ui/unsized/unsized-fn-arg.stderr new file mode 100644 index 000000000..404fa5291 --- /dev/null +++ b/src/test/ui/unsized/unsized-fn-arg.stderr @@ -0,0 +1,22 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/unsized-fn-arg.rs:5:17 + | +LL | fn f(t: T) {} + | - ^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = help: unsized fn params are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f(t: T) {} +LL + fn f(t: T) {} + | +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn f(t: &T) {} + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-fn-param.rs b/src/test/ui/unsized/unsized-fn-param.rs new file mode 100644 index 000000000..32efc7e17 --- /dev/null +++ b/src/test/ui/unsized/unsized-fn-param.rs @@ -0,0 +1,20 @@ +use std::convert::AsRef; +use std::path::Path; + +fn foo11(_bar: &dyn AsRef, _baz: &str) {} +fn foo12(_bar: &str, _baz: &dyn AsRef) {} + +fn foo21(_bar: &dyn AsRef, _baz: &str) {} +fn foo22(_bar: &str, _baz: &dyn AsRef) {} + +fn main() { + foo11("bar", &"baz"); //~ ERROR the size for values of type + foo11(&"bar", &"baz"); + foo12(&"bar", "baz"); //~ ERROR the size for values of type + foo12(&"bar", &"baz"); + + foo21("bar", &"baz"); //~ ERROR the size for values of type + foo21(&"bar", &"baz"); + foo22(&"bar", "baz"); //~ ERROR the size for values of type + foo22(&"bar", &"baz"); +} diff --git a/src/test/ui/unsized/unsized-fn-param.stderr b/src/test/ui/unsized/unsized-fn-param.stderr new file mode 100644 index 000000000..0221ef16b --- /dev/null +++ b/src/test/ui/unsized/unsized-fn-param.stderr @@ -0,0 +1,63 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-fn-param.rs:11:11 + | +LL | foo11("bar", &"baz"); + | ----- ^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `str` + = note: required for the cast from `str` to the object type `dyn AsRef` +help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + | +LL | foo11(&"bar", &"baz"); + | + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-fn-param.rs:13:19 + | +LL | foo12(&"bar", "baz"); + | ----- ^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `str` + = note: required for the cast from `str` to the object type `dyn AsRef` +help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + | +LL | foo12(&"bar", &"baz"); + | + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-fn-param.rs:16:11 + | +LL | foo21("bar", &"baz"); + | ----- ^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `str` + = note: required for the cast from `str` to the object type `dyn AsRef` +help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + | +LL | foo21(&"bar", &"baz"); + | + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized-fn-param.rs:18:19 + | +LL | foo22(&"bar", "baz"); + | ----- ^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `str` + = note: required for the cast from `str` to the object type `dyn AsRef` +help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + | +LL | foo22(&"bar", &"baz"); + | + + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.rs b/src/test/ui/unsized/unsized-inherent-impl-self-type.rs new file mode 100644 index 000000000..8bdf80c94 --- /dev/null +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.rs @@ -0,0 +1,11 @@ +// Test sized-ness checking in substitution in impls. + +// impl - struct + +struct S5(Y); + +impl S5 { + //~^ ERROR the size for values of type +} + +fn main() { } diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr new file mode 100644 index 000000000..a952aa063 --- /dev/null +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -0,0 +1,29 @@ +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized-inherent-impl-self-type.rs:7:17 + | +LL | impl S5 { + | - ^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required by a bound in `S5` + --> $DIR/unsized-inherent-impl-self-type.rs:5:11 + | +LL | struct S5(Y); + | ^ required by this bound in `S5` +help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` + --> $DIR/unsized-inherent-impl-self-type.rs:5:11 + | +LL | struct S5(Y); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `Y: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - impl S5 { +LL + impl S5 { + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-struct.rs b/src/test/ui/unsized/unsized-struct.rs new file mode 100644 index 000000000..bfa5aa0a5 --- /dev/null +++ b/src/test/ui/unsized/unsized-struct.rs @@ -0,0 +1,18 @@ +fn is_sized() { } +fn not_sized() { } + +struct Foo { data: T } +fn foo1() { not_sized::>() } // Hunky dory. +fn foo2() { not_sized::>() } +//~^ ERROR the size for values of type +// +// Not OK: `T` is not sized. + +struct Bar { data: T } +fn bar1() { not_sized::>() } +fn bar2() { is_sized::>() } +//~^ ERROR the size for values of type +// +// Not OK: `Bar` is not sized, but it should be. + +fn main() { } diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr new file mode 100644 index 000000000..c9510e92f --- /dev/null +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -0,0 +1,53 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/unsized-struct.rs:6:36 + | +LL | fn foo2() { not_sized::>() } + | - ^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required by a bound in `Foo` + --> $DIR/unsized-struct.rs:4:12 + | +LL | struct Foo { data: T } + | ^ required by this bound in `Foo` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/unsized-struct.rs:4:12 + | +LL | struct Foo { data: T } + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn foo2() { not_sized::>() } +LL + fn foo2() { not_sized::>() } + | + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/unsized-struct.rs:13:24 + | +LL | fn bar2() { is_sized::>() } + | - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required because it appears within the type `Bar` + --> $DIR/unsized-struct.rs:11:8 + | +LL | struct Bar { data: T } + | ^^^ +note: required by a bound in `is_sized` + --> $DIR/unsized-struct.rs:1:13 + | +LL | fn is_sized() { } + | ^ required by this bound in `is_sized` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn bar2() { is_sized::>() } +LL + fn bar2() { is_sized::>() } + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.rs b/src/test/ui/unsized/unsized-trait-impl-self-type.rs new file mode 100644 index 000000000..df571a833 --- /dev/null +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.rs @@ -0,0 +1,14 @@ +// Test sized-ness checking in substitution in impls. + +// impl - struct +trait T3 { + fn foo(&self, z: &Z); +} + +struct S5(Y); + +impl T3 for S5 { + //~^ ERROR the size for values of type +} + +fn main() { } diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr new file mode 100644 index 000000000..f6ba9a80c --- /dev/null +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr @@ -0,0 +1,29 @@ +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized-trait-impl-self-type.rs:10:27 + | +LL | impl T3 for S5 { + | - ^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required by a bound in `S5` + --> $DIR/unsized-trait-impl-self-type.rs:8:11 + | +LL | struct S5(Y); + | ^ required by this bound in `S5` +help: you could relax the implicit `Sized` bound on `Y` if it were used through indirection like `&Y` or `Box` + --> $DIR/unsized-trait-impl-self-type.rs:8:11 + | +LL | struct S5(Y); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `Y: ?Sized`... +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - impl T3 for S5 { +LL + impl T3 for S5 { + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.rs b/src/test/ui/unsized/unsized-trait-impl-trait-arg.rs new file mode 100644 index 000000000..96e7e371f --- /dev/null +++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.rs @@ -0,0 +1,12 @@ +// Test sized-ness checking in substitution in impls. + +// impl - unbounded +trait T2 { + fn foo(&self, z: Z); +} +struct S4(Box); +impl T2 for S4 { + //~^ ERROR the size for values of type +} + +fn main() { } diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr new file mode 100644 index 000000000..f81487d52 --- /dev/null +++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -0,0 +1,26 @@ +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized-trait-impl-trait-arg.rs:8:17 + | +LL | impl T2 for S4 { + | - ^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required by a bound in `T2` + --> $DIR/unsized-trait-impl-trait-arg.rs:4:10 + | +LL | trait T2 { + | ^ required by this bound in `T2` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - impl T2 for S4 { +LL + impl T2 for S4 { + | +help: consider relaxing the implicit `Sized` restriction + | +LL | trait T2 { + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized-tuple-impls.rs b/src/test/ui/unsized/unsized-tuple-impls.rs new file mode 100644 index 000000000..5e385f33b --- /dev/null +++ b/src/test/ui/unsized/unsized-tuple-impls.rs @@ -0,0 +1,21 @@ +// run-pass + +#![feature(unsized_tuple_coercion)] + +use std::collections::HashSet; + +fn main() { + let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]); + let y : &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]); + let mut a = [y, x]; + a.sort(); + assert_eq!(a, [x, y]); + + assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]"); + + let mut h = HashSet::new(); + h.insert(x); + h.insert(y); + assert!(h.contains(x)); + assert!(h.contains(y)); +} diff --git a/src/test/ui/unsized/unsized.rs b/src/test/ui/unsized/unsized.rs new file mode 100644 index 000000000..54304834d --- /dev/null +++ b/src/test/ui/unsized/unsized.rs @@ -0,0 +1,25 @@ +// run-pass + +#![allow(type_alias_bounds)] +#![allow(dead_code)] +// Test syntax checks for `?Sized` syntax. + +use std::marker::PhantomData; + +trait T1 { } +pub trait T2 { } +trait T3 : T2 { } +trait T4 { } +trait T5 { } +trait T6 { } +trait T7 { } +trait T8 { } +trait T9 { } +struct S1(PhantomData); +enum E { E1(PhantomData) } +impl T1 for S1 {} +fn f() {} +type TT = T; + +pub fn main() { +} diff --git a/src/test/ui/unsized/unsized2.rs b/src/test/ui/unsized/unsized2.rs new file mode 100644 index 000000000..bbeb00d5f --- /dev/null +++ b/src/test/ui/unsized/unsized2.rs @@ -0,0 +1,96 @@ +// run-pass + +#![allow(unconditional_recursion)] +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] + +// Test sized-ness checking in substitution. + +use std::marker; + +// Unbounded. +fn f1(x: &X) { + f1::(x); +} +fn f2(x: &X) { + f1::(x); + f2::(x); +} + +// Bounded. +trait T { fn dummy(&self) { } } +fn f3(x: &X) { + f3::(x); +} +fn f4(x: &X) { + f3::(x); + f4::(x); +} + +// Self type. +trait T2 { + fn f() -> Box; +} +struct S; +impl T2 for S { + fn f() -> Box { + Box::new(S) + } +} +fn f5(x: &X) { + let _: Box = T2::f(); +} +fn f6(x: &X) { + let _: Box = T2::f(); +} + +trait T3 { + fn f() -> Box; +} +impl T3 for S { + fn f() -> Box { + Box::new(S) + } +} +fn f7(x: &X) { + // This is valid, but the unsized bound on X is irrelevant because any type + // which implements T3 must have statically known size. + let _: Box = T3::f(); +} + +trait T4 { + fn dummy(&self) { } + fn m1(&self, x: &dyn T4, y: X); + fn m2(&self, x: &dyn T5, y: X); +} +trait T5 { + fn dummy(&self) { } + // not an error (for now) + fn m1(&self, x: &dyn T4); + fn m2(&self, x: &dyn T5); +} + +trait T6 { + fn dummy(&self) { } + fn m1(&self, x: &dyn T4); + fn m2(&self, x: &dyn T5); +} +trait T7 { + fn dummy(&self) { } + // not an error (for now) + fn m1(&self, x: &dyn T4); + fn m2(&self, x: &dyn T5); +} + +// The last field in a struct may be unsized +struct S2 { + f: X, +} +struct S3 { + f1: isize, + f2: X, +} + +pub fn main() { +} diff --git a/src/test/ui/unsized/unsized3-rpass.rs b/src/test/ui/unsized/unsized3-rpass.rs new file mode 100644 index 000000000..4d5e89575 --- /dev/null +++ b/src/test/ui/unsized/unsized3-rpass.rs @@ -0,0 +1,93 @@ +// run-pass +// Test structs with always-unsized fields. + +#![allow(warnings)] +#![feature(unsize, ptr_metadata)] + +use std::mem; +use std::ptr; +use std::slice; + +struct Foo { + f: [T], +} + +struct Bar { + f1: usize, + f2: [usize], +} + +struct Baz { + f1: usize, + f2: str, +} + +trait Tr { + fn foo(&self) -> usize; +} + +struct St { + f: usize, +} + +impl Tr for St { + fn foo(&self) -> usize { + self.f + } +} + +struct Qux<'a> { + f: Tr + 'a, +} + +pub fn main() { + let _: &Foo; + let _: &Bar; + let _: &Baz; + + let _: Box>; + let _: Box; + let _: Box; + + let _ = mem::size_of::>>(); + let _ = mem::size_of::>(); + let _ = mem::size_of::>(); + + unsafe { + struct Foo_ { + f: [T; 3], + } + + let data: Box> = Box::new(Foo_ { f: [1, 2, 3] }); + let x: &Foo = mem::transmute(slice::from_raw_parts(&*data, 3)); + assert_eq!(x.f.len(), 3); + assert_eq!(x.f[0], 1); + + struct Baz_ { + f1: usize, + f2: [u8; 5], + } + + let data: Box<_> = + Box::new(Baz_ { f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] }); + let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5)); + assert_eq!(x.f1, 42); + let chs: Vec = x.f2.chars().collect(); + assert_eq!(chs.len(), 5); + assert_eq!(chs[0], 'a'); + assert_eq!(chs[1], 'b'); + assert_eq!(chs[2], 'c'); + assert_eq!(chs[3], 'd'); + assert_eq!(chs[4], 'e'); + + struct Qux_ { + f: St, + } + + let obj: Box = Box::new(St { f: 42 }); + let obj: &Tr = &*obj; + let data: Box<_> = Box::new(Qux_ { f: St { f: 234 } }); + let x: &Qux = &*ptr::from_raw_parts::((&*data as *const _).cast(), ptr::metadata(obj)); + assert_eq!(x.f.foo(), 234); + } +} diff --git a/src/test/ui/unsized/unsized3.rs b/src/test/ui/unsized/unsized3.rs new file mode 100644 index 000000000..af76aca2c --- /dev/null +++ b/src/test/ui/unsized/unsized3.rs @@ -0,0 +1,50 @@ +// Test sized-ness checking in substitution within fn bodies.. + +use std::marker; + +// Unbounded. +fn f1(x: &X) { + f2::(x); + //~^ ERROR the size for values of type +} +fn f2(x: &X) { +} + +// Bounded. +trait T { + fn foo(&self) { } +} +fn f3(x: &X) { + f4::(x); + //~^ ERROR the size for values of type +} +fn f4(x: &X) { +} + +fn f5(x: &Y) {} +fn f6(x: &X) {} + +// Test with unsized struct. +struct S { + x: X, +} + +fn f8(x1: &S, x2: &S) { + f5(x1); + //~^ ERROR the size for values of type + f6(x2); // ok +} + +// Test some tuples. +fn f9(x1: Box>) { + f5(&(*x1, 34)); + //~^ ERROR the size for values of type +} + +fn f10(x1: Box>) { + f5(&(32, *x1)); + //~^ ERROR the size for values of type + //~| ERROR the size for values of type +} + +pub fn main() {} diff --git a/src/test/ui/unsized/unsized3.stderr b/src/test/ui/unsized/unsized3.stderr new file mode 100644 index 000000000..d64091b15 --- /dev/null +++ b/src/test/ui/unsized/unsized3.stderr @@ -0,0 +1,159 @@ +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized3.rs:7:13 + | +LL | fn f1(x: &X) { + | - this type parameter needs to be `std::marker::Sized` +LL | f2::(x); + | ------- ^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | +note: required by a bound in `f2` + --> $DIR/unsized3.rs:10:7 + | +LL | fn f2(x: &X) { + | ^ required by this bound in `f2` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f1(x: &X) { +LL + fn f1(x: &X) { + | +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f2(x: &X) { + | ++++++++ + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized3.rs:18:13 + | +LL | fn f3(x: &X) { + | - this type parameter needs to be `std::marker::Sized` +LL | f4::(x); + | ------- ^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | +note: required by a bound in `f4` + --> $DIR/unsized3.rs:21:7 + | +LL | fn f4(x: &X) { + | ^ required by this bound in `f4` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f3(x: &X) { +LL + fn f3(x: &X) { + | +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f4(x: &X) { + | ++++++++ + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized3.rs:33:8 + | +LL | fn f8(x1: &S, x2: &S) { + | - this type parameter needs to be `std::marker::Sized` +LL | f5(x1); + | -- ^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | +note: required because it appears within the type `S` + --> $DIR/unsized3.rs:28:8 + | +LL | struct S { + | ^ +note: required by a bound in `f5` + --> $DIR/unsized3.rs:24:7 + | +LL | fn f5(x: &Y) {} + | ^ required by this bound in `f5` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f8(x1: &S, x2: &S) { +LL + fn f8(x1: &S, x2: &S) { + | +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f5(x: &Y) {} + | ++++++++ + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized3.rs:40:8 + | +LL | fn f9(x1: Box>) { + | - this type parameter needs to be `std::marker::Sized` +LL | f5(&(*x1, 34)); + | -- ^^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | +note: required because it appears within the type `S` + --> $DIR/unsized3.rs:28:8 + | +LL | struct S { + | ^ + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f9(x1: Box>) { +LL + fn f9(x1: Box>) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized3.rs:45:9 + | +LL | fn f10(x1: Box>) { + | - this type parameter needs to be `std::marker::Sized` +LL | f5(&(32, *x1)); + | -- ^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | +note: required because it appears within the type `S` + --> $DIR/unsized3.rs:28:8 + | +LL | struct S { + | ^ + = note: required because it appears within the type `({integer}, S)` + = note: tuples must have a statically known size to be initialized +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f10(x1: Box>) { +LL + fn f10(x1: Box>) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized3.rs:45:8 + | +LL | fn f10(x1: Box>) { + | - this type parameter needs to be `std::marker::Sized` +LL | f5(&(32, *x1)); + | -- ^^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | +note: required because it appears within the type `S` + --> $DIR/unsized3.rs:28:8 + | +LL | struct S { + | ^ + = note: required because it appears within the type `({integer}, S)` +note: required by a bound in `f5` + --> $DIR/unsized3.rs:24:7 + | +LL | fn f5(x: &Y) {} + | ^ required by this bound in `f5` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f10(x1: Box>) { +LL + fn f10(x1: Box>) { + | +help: consider relaxing the implicit `Sized` restriction + | +LL | fn f5(x: &Y) {} + | ++++++++ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized5.rs b/src/test/ui/unsized/unsized5.rs new file mode 100644 index 000000000..befd2244d --- /dev/null +++ b/src/test/ui/unsized/unsized5.rs @@ -0,0 +1,34 @@ +// Test `?Sized` types not allowed in fields (except the last one). + +struct S1 { + f1: X, + //~^ ERROR the size for values of type + f2: isize, +} +struct S2 { + f: isize, + g: X, + //~^ ERROR the size for values of type + h: isize, +} +struct S3 { + f: str, + //~^ ERROR the size for values of type + g: [usize] +} +struct S4 { + f: [u8], + //~^ ERROR the size for values of type + g: usize +} +enum E { + V1(X, isize), + //~^ ERROR the size for values of type +} +enum F { + V2{f1: X, f: isize}, + //~^ ERROR the size for values of type +} + +pub fn main() { +} diff --git a/src/test/ui/unsized/unsized5.stderr b/src/test/ui/unsized/unsized5.stderr new file mode 100644 index 000000000..03ed0c457 --- /dev/null +++ b/src/test/ui/unsized/unsized5.stderr @@ -0,0 +1,136 @@ +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized5.rs:4:9 + | +LL | struct S1 { + | - this type parameter needs to be `std::marker::Sized` +LL | f1: X, + | ^ doesn't have a size known at compile-time + | + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - struct S1 { +LL + struct S1 { + | +help: borrowed types always have a statically known size + | +LL | f1: &X, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | f1: Box, + | ++++ + + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized5.rs:10:8 + | +LL | struct S2 { + | - this type parameter needs to be `std::marker::Sized` +LL | f: isize, +LL | g: X, + | ^ doesn't have a size known at compile-time + | + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - struct S2 { +LL + struct S2 { + | +help: borrowed types always have a statically known size + | +LL | g: &X, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | g: Box, + | ++++ + + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized5.rs:15:8 + | +LL | f: str, + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | f: &str, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | f: Box, + | ++++ + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized5.rs:20:8 + | +LL | f: [u8], + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | f: &[u8], + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | f: Box<[u8]>, + | ++++ + + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized5.rs:25:8 + | +LL | enum E { + | - this type parameter needs to be `std::marker::Sized` +LL | V1(X, isize), + | ^ doesn't have a size known at compile-time + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - enum E { +LL + enum E { + | +help: borrowed types always have a statically known size + | +LL | V1(&X, isize), + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | V1(Box, isize), + | ++++ + + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized5.rs:29:12 + | +LL | enum F { + | - this type parameter needs to be `std::marker::Sized` +LL | V2{f1: X, f: isize}, + | ^ doesn't have a size known at compile-time + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - enum F { +LL + enum F { + | +help: borrowed types always have a statically known size + | +LL | V2{f1: &X, f: isize}, + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | V2{f1: Box, f: isize}, + | ++++ + + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized6.rs b/src/test/ui/unsized/unsized6.rs new file mode 100644 index 000000000..79133554d --- /dev/null +++ b/src/test/ui/unsized/unsized6.rs @@ -0,0 +1,44 @@ +// Test `?Sized` local variables. + +trait T {} + +fn f1(x: &X) { + let _: W; // <-- this is OK, no bindings created, no initializer. + let _: (isize, (X, isize)); + //~^ ERROR the size for values of type + let y: Y; + //~^ ERROR the size for values of type + let y: (isize, (Z, usize)); + //~^ ERROR the size for values of type +} +fn f2(x: &X) { + let y: X; + //~^ ERROR the size for values of type + let y: (isize, (Y, isize)); + //~^ ERROR the size for values of type +} + +fn f3(x1: Box, x2: Box, x3: Box) { + let y: X = *x1; + //~^ ERROR the size for values of type + let y = *x2; + //~^ ERROR the size for values of type + let (y, z) = (*x3, 4); + //~^ ERROR the size for values of type +} +fn f4(x1: Box, x2: Box, x3: Box) { + let y: X = *x1; + //~^ ERROR the size for values of type + let y = *x2; + //~^ ERROR the size for values of type + let (y, z) = (*x3, 4); + //~^ ERROR the size for values of type +} + +fn g1(x: X) {} +//~^ ERROR the size for values of type +fn g2(x: X) {} +//~^ ERROR the size for values of type + +pub fn main() { +} diff --git a/src/test/ui/unsized/unsized6.stderr b/src/test/ui/unsized/unsized6.stderr new file mode 100644 index 000000000..011f2b426 --- /dev/null +++ b/src/test/ui/unsized/unsized6.stderr @@ -0,0 +1,222 @@ +error[E0277]: the size for values of type `Y` cannot be known at compilation time + --> $DIR/unsized6.rs:9:9 + | +LL | fn f1(x: &X) { + | - this type parameter needs to be `std::marker::Sized` +... +LL | let y: Y; + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f1(x: &X) { +LL + fn f1(x: &X) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:7:12 + | +LL | fn f1(x: &X) { + | - this type parameter needs to be `std::marker::Sized` +LL | let _: W; // <-- this is OK, no bindings created, no initializer. +LL | let _: (isize, (X, isize)); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f1(x: &X) { +LL + fn f1(x: &X) { + | + +error[E0277]: the size for values of type `Z` cannot be known at compilation time + --> $DIR/unsized6.rs:11:12 + | +LL | fn f1(x: &X) { + | - this type parameter needs to be `std::marker::Sized` +... +LL | let y: (isize, (Z, usize)); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f1(x: &X) { +LL + fn f1(x: &X) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:15:9 + | +LL | fn f2(x: &X) { + | - this type parameter needs to be `std::marker::Sized` +LL | let y: X; + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f2(x: &X) { +LL + fn f2(x: &X) { + | + +error[E0277]: the size for values of type `Y` cannot be known at compilation time + --> $DIR/unsized6.rs:17:12 + | +LL | fn f2(x: &X) { + | - this type parameter needs to be `std::marker::Sized` +... +LL | let y: (isize, (Y, isize)); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f2(x: &X) { +LL + fn f2(x: &X) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:22:9 + | +LL | fn f3(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `std::marker::Sized` +LL | let y: X = *x1; + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f3(x1: Box, x2: Box, x3: Box) { +LL + fn f3(x1: Box, x2: Box, x3: Box) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:24:9 + | +LL | fn f3(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `std::marker::Sized` +... +LL | let y = *x2; + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f3(x1: Box, x2: Box, x3: Box) { +LL + fn f3(x1: Box, x2: Box, x3: Box) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:26:10 + | +LL | fn f3(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `std::marker::Sized` +... +LL | let (y, z) = (*x3, 4); + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f3(x1: Box, x2: Box, x3: Box) { +LL + fn f3(x1: Box, x2: Box, x3: Box) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:30:9 + | +LL | fn f4(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `std::marker::Sized` +LL | let y: X = *x1; + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f4(x1: Box, x2: Box, x3: Box) { +LL + fn f4(x1: Box, x2: Box, x3: Box) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:32:9 + | +LL | fn f4(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `std::marker::Sized` +... +LL | let y = *x2; + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f4(x1: Box, x2: Box, x3: Box) { +LL + fn f4(x1: Box, x2: Box, x3: Box) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:34:10 + | +LL | fn f4(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `std::marker::Sized` +... +LL | let (y, z) = (*x3, 4); + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn f4(x1: Box, x2: Box, x3: Box) { +LL + fn f4(x1: Box, x2: Box, x3: Box) { + | + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:38:18 + | +LL | fn g1(x: X) {} + | - ^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = help: unsized fn params are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn g1(x: X) {} +LL + fn g1(x: X) {} + | +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn g1(x: &X) {} + | + + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized6.rs:40:22 + | +LL | fn g2(x: X) {} + | - ^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | + = help: unsized fn params are gated as an unstable feature +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn g2(x: X) {} +LL + fn g2(x: X) {} + | +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn g2(x: &X) {} + | + + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized/unsized7.rs b/src/test/ui/unsized/unsized7.rs new file mode 100644 index 000000000..422a78481 --- /dev/null +++ b/src/test/ui/unsized/unsized7.rs @@ -0,0 +1,16 @@ +// Test sized-ness checking in substitution in impls. + +trait T {} + +// I would like these to fail eventually. +// impl - bounded +trait T1 { + fn dummy(&self) -> Z; +} + +struct S3(Box); +impl T1 for S3 { + //~^ ERROR the size for values of type +} + +fn main() { } diff --git a/src/test/ui/unsized/unsized7.stderr b/src/test/ui/unsized/unsized7.stderr new file mode 100644 index 000000000..1555b9df4 --- /dev/null +++ b/src/test/ui/unsized/unsized7.stderr @@ -0,0 +1,26 @@ +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized7.rs:12:21 + | +LL | impl T1 for S3 { + | - ^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `std::marker::Sized` + | +note: required by a bound in `T1` + --> $DIR/unsized7.rs:7:10 + | +LL | trait T1 { + | ^ required by this bound in `T1` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - impl T1 for S3 { +LL + impl T1 for S3 { + | +help: consider relaxing the implicit `Sized` restriction + | +LL | trait T1 { + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. -- cgit v1.2.3