diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/dst | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/dst')
28 files changed, 866 insertions, 0 deletions
diff --git a/src/test/ui/dst/dst-bad-assign-2.rs b/src/test/ui/dst/dst-bad-assign-2.rs new file mode 100644 index 000000000..7ba31bf2e --- /dev/null +++ b/src/test/ui/dst/dst-bad-assign-2.rs @@ -0,0 +1,38 @@ +// Forbid assignment into a dynamically sized type. + +struct Fat<T: ?Sized> { + f1: isize, + f2: &'static str, + ptr: T +} + +#[derive(PartialEq,Eq)] +struct Bar; + +#[derive(PartialEq,Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +pub fn main() { + // Assignment. + let f5: &mut Fat<dyn ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} }; + let z: Box<dyn ToBar> = Box::new(Bar1 {f: 36}); + f5.ptr = *z; + //~^ ERROR the size for values of type + +} diff --git a/src/test/ui/dst/dst-bad-assign-2.stderr b/src/test/ui/dst/dst-bad-assign-2.stderr new file mode 100644 index 000000000..6c9e2971c --- /dev/null +++ b/src/test/ui/dst/dst-bad-assign-2.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time + --> $DIR/dst-bad-assign-2.rs:35:5 + | +LL | f5.ptr = *z; + | ^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn ToBar` + = note: the left-hand-side of an assignment must have a statically known size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-bad-assign-3.rs b/src/test/ui/dst/dst-bad-assign-3.rs new file mode 100644 index 000000000..d05b3937c --- /dev/null +++ b/src/test/ui/dst/dst-bad-assign-3.rs @@ -0,0 +1,39 @@ +// Forbid assignment into a dynamically sized type. + +#![feature(unsized_tuple_coercion)] + +type Fat<T> = (isize, &'static str, T); + +#[derive(PartialEq,Eq)] +struct Bar; + +#[derive(PartialEq,Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +pub fn main() { + // Assignment. + let f5: &mut Fat<dyn ToBar> = &mut (5, "some str", Bar1 {f :42}); + let z: Box<dyn ToBar> = Box::new(Bar1 {f: 36}); + f5.2 = Bar1 {f: 36}; + //~^ ERROR mismatched types + //~| expected trait object `dyn ToBar`, found struct `Bar1` + //~| expected trait object `dyn ToBar` + //~| found struct `Bar1` + //~| ERROR the size for values of type +} diff --git a/src/test/ui/dst/dst-bad-assign-3.stderr b/src/test/ui/dst/dst-bad-assign-3.stderr new file mode 100644 index 000000000..b326dbbbc --- /dev/null +++ b/src/test/ui/dst/dst-bad-assign-3.stderr @@ -0,0 +1,24 @@ +error[E0308]: mismatched types + --> $DIR/dst-bad-assign-3.rs:33:12 + | +LL | f5.2 = Bar1 {f: 36}; + | ---- ^^^^^^^^^^^^ expected trait object `dyn ToBar`, found struct `Bar1` + | | + | expected due to the type of this binding + | + = note: expected trait object `dyn ToBar` + found struct `Bar1` + +error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time + --> $DIR/dst-bad-assign-3.rs:33:5 + | +LL | f5.2 = Bar1 {f: 36}; + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn ToBar` + = note: the left-hand-side of an assignment must have a statically known size + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-bad-assign.rs b/src/test/ui/dst/dst-bad-assign.rs new file mode 100644 index 000000000..496e01ae0 --- /dev/null +++ b/src/test/ui/dst/dst-bad-assign.rs @@ -0,0 +1,41 @@ +// Forbid assignment into a dynamically sized type. + +struct Fat<T: ?Sized> { + f1: isize, + f2: &'static str, + ptr: T +} + +#[derive(PartialEq,Eq)] +struct Bar; + +#[derive(PartialEq,Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +pub fn main() { + // Assignment. + let f5: &mut Fat<dyn ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} }; + let z: Box<dyn ToBar> = Box::new(Bar1 {f: 36}); + f5.ptr = Bar1 {f: 36}; + //~^ ERROR mismatched types + //~| expected trait object `dyn ToBar`, found struct `Bar1` + //~| expected trait object `dyn ToBar` + //~| found struct `Bar1` + //~| ERROR the size for values of type +} diff --git a/src/test/ui/dst/dst-bad-assign.stderr b/src/test/ui/dst/dst-bad-assign.stderr new file mode 100644 index 000000000..614f21387 --- /dev/null +++ b/src/test/ui/dst/dst-bad-assign.stderr @@ -0,0 +1,24 @@ +error[E0308]: mismatched types + --> $DIR/dst-bad-assign.rs:35:14 + | +LL | f5.ptr = Bar1 {f: 36}; + | ------ ^^^^^^^^^^^^ expected trait object `dyn ToBar`, found struct `Bar1` + | | + | expected due to the type of this binding + | + = note: expected trait object `dyn ToBar` + found struct `Bar1` + +error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time + --> $DIR/dst-bad-assign.rs:35:5 + | +LL | f5.ptr = Bar1 {f: 36}; + | ^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn ToBar` + = note: the left-hand-side of an assignment must have a statically known size + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-bad-coerce1.rs b/src/test/ui/dst/dst-bad-coerce1.rs new file mode 100644 index 000000000..7ef237e39 --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce1.rs @@ -0,0 +1,36 @@ +// Attempt to change the type as well as unsizing. + +#![feature(unsized_tuple_coercion)] + +struct Fat<T: ?Sized> { + ptr: T +} + +struct Foo; +trait Bar { fn bar(&self) {} } + +pub fn main() { + // With a vec of isize. + let f1 = Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = &f1; + let f3: &Fat<[usize]> = f2; + //~^ ERROR mismatched types + + // With a trait. + let f1 = Fat { ptr: Foo }; + let f2: &Fat<Foo> = &f1; + let f3: &Fat<dyn Bar> = f2; + //~^ ERROR `Foo: Bar` is not satisfied + + // Tuple with a vec of isize. + let f1 = ([1, 2, 3],); + let f2: &([isize; 3],) = &f1; + let f3: &([usize],) = f2; + //~^ ERROR mismatched types + + // Tuple with a trait. + let f1 = (Foo,); + let f2: &(Foo,) = &f1; + let f3: &(dyn Bar,) = f2; + //~^ ERROR `Foo: Bar` is not satisfied +} diff --git a/src/test/ui/dst/dst-bad-coerce1.stderr b/src/test/ui/dst/dst-bad-coerce1.stderr new file mode 100644 index 000000000..594acff85 --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce1.stderr @@ -0,0 +1,42 @@ +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce1.rs:16:29 + | +LL | let f3: &Fat<[usize]> = f2; + | ------------- ^^ expected slice `[usize]`, found array `[isize; 3]` + | | + | expected due to this + | + = note: expected reference `&Fat<[usize]>` + found reference `&Fat<[isize; 3]>` + +error[E0277]: the trait bound `Foo: Bar` is not satisfied + --> $DIR/dst-bad-coerce1.rs:22:29 + | +LL | let f3: &Fat<dyn Bar> = f2; + | ^^ the trait `Bar` is not implemented for `Foo` + | + = note: required for the cast from `Foo` to the object type `dyn Bar` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce1.rs:28:27 + | +LL | let f3: &([usize],) = f2; + | ----------- ^^ expected slice `[usize]`, found array `[isize; 3]` + | | + | expected due to this + | + = note: expected reference `&([usize],)` + found reference `&([isize; 3],)` + +error[E0277]: the trait bound `Foo: Bar` is not satisfied + --> $DIR/dst-bad-coerce1.rs:34:27 + | +LL | let f3: &(dyn Bar,) = f2; + | ^^ the trait `Bar` is not implemented for `Foo` + | + = note: required for the cast from `Foo` to the object type `dyn Bar` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-bad-coerce2.rs b/src/test/ui/dst/dst-bad-coerce2.rs new file mode 100644 index 000000000..e7ce20b89 --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce2.rs @@ -0,0 +1,31 @@ +// Attempt to change the mutability as well as unsizing. + +struct Fat<T: ?Sized> { + ptr: T +} + +struct Foo; +trait Bar {} +impl Bar for Foo {} + +pub fn main() { + // With a vec of ints. + let f1 = Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = &f1; + let f3: &mut Fat<[isize]> = f2; //~ ERROR mismatched types + + // With a trait. + let f1 = Fat { ptr: Foo }; + let f2: &Fat<Foo> = &f1; + let f3: &mut Fat<dyn Bar> = f2; //~ ERROR mismatched types + + // Tuple with a vec of ints. + let f1 = ([1, 2, 3],); + let f2: &([isize; 3],) = &f1; + let f3: &mut ([isize],) = f2; //~ ERROR mismatched types + + // Tuple with a trait. + let f1 = (Foo,); + let f2: &(Foo,) = &f1; + let f3: &mut (dyn Bar,) = f2; //~ ERROR mismatched types +} diff --git a/src/test/ui/dst/dst-bad-coerce2.stderr b/src/test/ui/dst/dst-bad-coerce2.stderr new file mode 100644 index 000000000..3ded96cfb --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce2.stderr @@ -0,0 +1,47 @@ +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce2.rs:15:33 + | +LL | let f3: &mut Fat<[isize]> = f2; + | ----------------- ^^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut Fat<[isize]>` + found reference `&Fat<[isize; 3]>` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce2.rs:20:33 + | +LL | let f3: &mut Fat<dyn Bar> = f2; + | ----------------- ^^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut Fat<dyn Bar>` + found reference `&Fat<Foo>` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce2.rs:25:31 + | +LL | let f3: &mut ([isize],) = f2; + | --------------- ^^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut ([isize],)` + found reference `&([isize; 3],)` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce2.rs:30:31 + | +LL | let f3: &mut (dyn Bar,) = f2; + | --------------- ^^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut (dyn Bar,)` + found reference `&(Foo,)` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/dst/dst-bad-coerce3.rs b/src/test/ui/dst/dst-bad-coerce3.rs new file mode 100644 index 000000000..fd5ee3b57 --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce3.rs @@ -0,0 +1,37 @@ +// Attempt to extend the lifetime as well as unsizing. + +#![feature(unsized_tuple_coercion)] + +struct Fat<T: ?Sized> { + ptr: T +} + +struct Foo; +trait Bar { fn bar(&self) {} } +impl Bar for Foo {} + +fn baz<'a>() { + // With a vec of ints. + let f1 = Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = &f1; //~ ERROR `f1` does not live long enough + let f3: &'a Fat<[isize]> = f2; + + // With a trait. + let f1 = Fat { ptr: Foo }; + let f2: &Fat<Foo> = &f1; //~ ERROR `f1` does not live long enough + let f3: &'a Fat<dyn Bar> = f2; + + // Tuple with a vec of ints. + let f1 = ([1, 2, 3],); + let f2: &([isize; 3],) = &f1; //~ ERROR `f1` does not live long enough + let f3: &'a ([isize],) = f2; + + // Tuple with a trait. + let f1 = (Foo,); + let f2: &(Foo,) = &f1; //~ ERROR `f1` does not live long enough + let f3: &'a (dyn Bar,) = f2; +} + +pub fn main() { + baz(); +} diff --git a/src/test/ui/dst/dst-bad-coerce3.stderr b/src/test/ui/dst/dst-bad-coerce3.stderr new file mode 100644 index 000000000..957e98bbe --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce3.stderr @@ -0,0 +1,58 @@ +error[E0597]: `f1` does not live long enough + --> $DIR/dst-bad-coerce3.rs:16:32 + | +LL | fn baz<'a>() { + | -- lifetime `'a` defined here +... +LL | let f2: &Fat<[isize; 3]> = &f1; + | ^^^ borrowed value does not live long enough +LL | let f3: &'a Fat<[isize]> = f2; + | ---------------- type annotation requires that `f1` is borrowed for `'a` +... +LL | } + | - `f1` dropped here while still borrowed + +error[E0597]: `f1` does not live long enough + --> $DIR/dst-bad-coerce3.rs:21:25 + | +LL | fn baz<'a>() { + | -- lifetime `'a` defined here +... +LL | let f2: &Fat<Foo> = &f1; + | ^^^ borrowed value does not live long enough +LL | let f3: &'a Fat<dyn Bar> = f2; + | ---------------- type annotation requires that `f1` is borrowed for `'a` +... +LL | } + | - `f1` dropped here while still borrowed + +error[E0597]: `f1` does not live long enough + --> $DIR/dst-bad-coerce3.rs:26:30 + | +LL | fn baz<'a>() { + | -- lifetime `'a` defined here +... +LL | let f2: &([isize; 3],) = &f1; + | ^^^ borrowed value does not live long enough +LL | let f3: &'a ([isize],) = f2; + | -------------- type annotation requires that `f1` is borrowed for `'a` +... +LL | } + | - `f1` dropped here while still borrowed + +error[E0597]: `f1` does not live long enough + --> $DIR/dst-bad-coerce3.rs:31:23 + | +LL | fn baz<'a>() { + | -- lifetime `'a` defined here +... +LL | let f2: &(Foo,) = &f1; + | ^^^ borrowed value does not live long enough +LL | let f3: &'a (dyn Bar,) = f2; + | -------------- type annotation requires that `f1` is borrowed for `'a` +LL | } + | - `f1` dropped here while still borrowed + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/dst/dst-bad-coerce4.rs b/src/test/ui/dst/dst-bad-coerce4.rs new file mode 100644 index 000000000..f63da60d2 --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce4.rs @@ -0,0 +1,25 @@ +// Attempt to coerce from unsized to sized. + +#![feature(unsized_tuple_coercion)] + +struct Fat<T: ?Sized> { + ptr: T +} + +pub fn main() { + // With a vec of isizes. + let f1: &Fat<[isize]> = &Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = f1; + //~^ ERROR mismatched types + //~| expected array `[isize; 3]`, found slice `[isize]` + //~| expected reference `&Fat<[isize; 3]>` + //~| found reference `&Fat<[isize]>` + + // Tuple with a vec of isizes. + let f1: &([isize],) = &([1, 2, 3],); + let f2: &([isize; 3],) = f1; + //~^ ERROR mismatched types + //~| expected array `[isize; 3]`, found slice `[isize]` + //~| expected reference `&([isize; 3],)` + //~| found reference `&([isize],)` +} diff --git a/src/test/ui/dst/dst-bad-coerce4.stderr b/src/test/ui/dst/dst-bad-coerce4.stderr new file mode 100644 index 000000000..4c9954f35 --- /dev/null +++ b/src/test/ui/dst/dst-bad-coerce4.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce4.rs:12:32 + | +LL | let f2: &Fat<[isize; 3]> = f1; + | ---------------- ^^ expected array `[isize; 3]`, found slice `[isize]` + | | + | expected due to this + | + = note: expected reference `&Fat<[isize; 3]>` + found reference `&Fat<[isize]>` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coerce4.rs:20:30 + | +LL | let f2: &([isize; 3],) = f1; + | -------------- ^^ expected array `[isize; 3]`, found slice `[isize]` + | | + | expected due to this + | + = note: expected reference `&([isize; 3],)` + found reference `&([isize],)` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/dst/dst-bad-coercions.rs b/src/test/ui/dst/dst-bad-coercions.rs new file mode 100644 index 000000000..bffef378c --- /dev/null +++ b/src/test/ui/dst/dst-bad-coercions.rs @@ -0,0 +1,26 @@ +// Test implicit coercions involving DSTs and raw pointers. + +struct S; +trait T {} +impl T for S {} + +struct Foo<T: ?Sized> { + f: T +} + +pub fn main() { + // Test that we cannot convert from *-ptr to &S and &T + let x: *const S = &S; + let y: &S = x; //~ ERROR mismatched types + let y: &dyn T = x; //~ ERROR mismatched types + + // Test that we cannot convert from *-ptr to &S and &T (mut version) + let x: *mut S = &mut S; + let y: &S = x; //~ ERROR mismatched types + let y: &dyn T = x; //~ ERROR mismatched types + + // Test that we cannot convert an immutable ptr to a mutable one using *-ptrs + let x: &mut dyn T = &S; //~ ERROR mismatched types + let x: *mut dyn T = &S; //~ ERROR mismatched types + let x: *mut S = &S; //~ ERROR mismatched types +} diff --git a/src/test/ui/dst/dst-bad-coercions.stderr b/src/test/ui/dst/dst-bad-coercions.stderr new file mode 100644 index 000000000..01f862ed5 --- /dev/null +++ b/src/test/ui/dst/dst-bad-coercions.stderr @@ -0,0 +1,80 @@ +error[E0308]: mismatched types + --> $DIR/dst-bad-coercions.rs:14:17 + | +LL | let y: &S = x; + | -- ^ expected `&S`, found *-ptr + | | + | expected due to this + | + = note: expected reference `&S` + found raw pointer `*const S` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coercions.rs:15:21 + | +LL | let y: &dyn T = x; + | ------ ^ expected `&dyn T`, found *-ptr + | | + | expected due to this + | + = note: expected reference `&dyn T` + found raw pointer `*const S` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coercions.rs:19:17 + | +LL | let y: &S = x; + | -- ^ expected `&S`, found *-ptr + | | + | expected due to this + | + = note: expected reference `&S` + found raw pointer `*mut S` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coercions.rs:20:21 + | +LL | let y: &dyn T = x; + | ------ ^ expected `&dyn T`, found *-ptr + | | + | expected due to this + | + = note: expected reference `&dyn T` + found raw pointer `*mut S` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coercions.rs:23:25 + | +LL | let x: &mut dyn T = &S; + | ---------- ^^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut dyn T` + found reference `&S` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coercions.rs:24:25 + | +LL | let x: *mut dyn T = &S; + | ---------- ^^ types differ in mutability + | | + | expected due to this + | + = note: expected raw pointer `*mut dyn T` + found reference `&S` + +error[E0308]: mismatched types + --> $DIR/dst-bad-coercions.rs:25:21 + | +LL | let x: *mut S = &S; + | ------ ^^ types differ in mutability + | | + | expected due to this + | + = note: expected raw pointer `*mut S` + found reference `&S` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/dst/dst-bad-deep-2.rs b/src/test/ui/dst/dst-bad-deep-2.rs new file mode 100644 index 000000000..e58739913 --- /dev/null +++ b/src/test/ui/dst/dst-bad-deep-2.rs @@ -0,0 +1,13 @@ +// Try to initialise a DST struct where the lost information is deeply nested. +// This is an error because it requires an unsized rvalue. This is a problem +// because it would require stack allocation of an unsized temporary (*g in the +// test). + +#![feature(unsized_tuple_coercion)] + +pub fn main() { + let f: ([isize; 3],) = ([5, 6, 7],); + let g: &([isize],) = &f; + let h: &(([isize],),) = &(*g,); + //~^ ERROR the size for values of type +} diff --git a/src/test/ui/dst/dst-bad-deep-2.stderr b/src/test/ui/dst/dst-bad-deep-2.stderr new file mode 100644 index 000000000..b22850814 --- /dev/null +++ b/src/test/ui/dst/dst-bad-deep-2.stderr @@ -0,0 +1,14 @@ +error[E0277]: the size for values of type `[isize]` cannot be known at compilation time + --> $DIR/dst-bad-deep-2.rs:11:30 + | +LL | let h: &(([isize],),) = &(*g,); + | ^^^^^ doesn't have a size known at compile-time + | + = help: within `(([isize],),)`, the trait `Sized` is not implemented for `[isize]` + = note: required because it appears within the type `([isize],)` + = note: required because it appears within the type `(([isize],),)` + = note: tuples must have a statically known size to be initialized + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-bad-deep.rs b/src/test/ui/dst/dst-bad-deep.rs new file mode 100644 index 000000000..a42672960 --- /dev/null +++ b/src/test/ui/dst/dst-bad-deep.rs @@ -0,0 +1,15 @@ +// Try to initialise a DST struct where the lost information is deeply nested. +// This is an error because it requires an unsized rvalue. This is a problem +// because it would require stack allocation of an unsized temporary (*g in the +// test). + +struct Fat<T: ?Sized> { + ptr: T +} + +pub fn main() { + let f: Fat<[isize; 3]> = Fat { ptr: [5, 6, 7] }; + let g: &Fat<[isize]> = &f; + let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g }; + //~^ ERROR the size for values of type +} diff --git a/src/test/ui/dst/dst-bad-deep.stderr b/src/test/ui/dst/dst-bad-deep.stderr new file mode 100644 index 000000000..98db79591 --- /dev/null +++ b/src/test/ui/dst/dst-bad-deep.stderr @@ -0,0 +1,17 @@ +error[E0277]: the size for values of type `[isize]` cannot be known at compilation time + --> $DIR/dst-bad-deep.rs:13:34 + | +LL | let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g }; + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `Fat<Fat<[isize]>>`, the trait `Sized` is not implemented for `[isize]` +note: required because it appears within the type `Fat<[isize]>` + --> $DIR/dst-bad-deep.rs:6:8 + | +LL | struct Fat<T: ?Sized> { + | ^^^ + = note: structs must have a statically known size to be initialized + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-index.rs b/src/test/ui/dst/dst-index.rs new file mode 100644 index 000000000..2f2c5df46 --- /dev/null +++ b/src/test/ui/dst/dst-index.rs @@ -0,0 +1,37 @@ +// Test that overloaded index expressions with DST result types +// can't be used as rvalues + +use std::ops::Index; +use std::fmt::Debug; + +#[derive(Copy, Clone)] +struct S; + +impl Index<usize> for S { + type Output = str; + + fn index(&self, _: usize) -> &str { + "hello" + } +} + +#[derive(Copy, Clone)] +struct T; + +impl Index<usize> for T { + type Output = dyn Debug + 'static; + + fn index<'a>(&'a self, idx: usize) -> &'a (dyn Debug + 'static) { + static x: usize = 42; + &x + } +} + +fn main() { + S[0]; + //~^ ERROR cannot move out of index of `S` + //~^^ ERROR E0161 + T[0]; + //~^ ERROR cannot move out of index of `T` + //~^^ ERROR E0161 +} diff --git a/src/test/ui/dst/dst-index.stderr b/src/test/ui/dst/dst-index.stderr new file mode 100644 index 000000000..d38af3f89 --- /dev/null +++ b/src/test/ui/dst/dst-index.stderr @@ -0,0 +1,28 @@ +error[E0161]: cannot move a value of type `str` + --> $DIR/dst-index.rs:31:5 + | +LL | S[0]; + | ^^^^ the size of `str` cannot be statically determined + +error[E0161]: cannot move a value of type `dyn Debug` + --> $DIR/dst-index.rs:34:5 + | +LL | T[0]; + | ^^^^ the size of `dyn Debug` cannot be statically determined + +error[E0507]: cannot move out of index of `S` + --> $DIR/dst-index.rs:31:5 + | +LL | S[0]; + | ^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of index of `T` + --> $DIR/dst-index.rs:34:5 + | +LL | T[0]; + | ^^^^ move occurs because value has type `dyn Debug`, which does not implement the `Copy` trait + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0161, E0507. +For more information about an error, try `rustc --explain E0161`. diff --git a/src/test/ui/dst/dst-object-from-unsized-type.rs b/src/test/ui/dst/dst-object-from-unsized-type.rs new file mode 100644 index 000000000..3cd5b1ed6 --- /dev/null +++ b/src/test/ui/dst/dst-object-from-unsized-type.rs @@ -0,0 +1,27 @@ +// Test that we cannot create objects from unsized types. + +trait Foo { fn foo(&self) {} } +impl Foo for str {} +impl Foo for [u8] {} + +fn test1<T: ?Sized + Foo>(t: &T) { + let u: &dyn Foo = t; + //~^ ERROR the size for values of type +} + +fn test2<T: ?Sized + Foo>(t: &T) { + let v: &dyn Foo = t as &dyn Foo; + //~^ ERROR the size for values of type +} + +fn test3() { + let _: &[&dyn Foo] = &["hi"]; + //~^ ERROR the size for values of type +} + +fn test4(x: &[u8]) { + let _: &dyn Foo = x as &dyn Foo; + //~^ ERROR the size for values of type +} + +fn main() { } diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr new file mode 100644 index 000000000..e24c96ebe --- /dev/null +++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr @@ -0,0 +1,51 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/dst-object-from-unsized-type.rs:8:23 + | +LL | fn test1<T: ?Sized + Foo>(t: &T) { + | - this type parameter needs to be `std::marker::Sized` +LL | let u: &dyn Foo = t; + | ^ doesn't have a size known at compile-time + | + = note: required for the cast from `T` to the object type `dyn Foo` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn test1<T: ?Sized + Foo>(t: &T) { +LL + fn test1<T: Foo>(t: &T) { + | + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/dst-object-from-unsized-type.rs:13:23 + | +LL | fn test2<T: ?Sized + Foo>(t: &T) { + | - this type parameter needs to be `std::marker::Sized` +LL | let v: &dyn Foo = t as &dyn Foo; + | ^ doesn't have a size known at compile-time + | + = note: required for the cast from `T` to the object type `dyn Foo` +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - fn test2<T: ?Sized + Foo>(t: &T) { +LL + fn test2<T: Foo>(t: &T) { + | + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/dst-object-from-unsized-type.rs:18:28 + | +LL | let _: &[&dyn Foo] = &["hi"]; + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: required for the cast from `str` to the object type `dyn Foo` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/dst-object-from-unsized-type.rs:23:23 + | +LL | let _: &dyn Foo = x as &dyn Foo; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: required for the cast from `[u8]` to the object type `dyn Foo` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-rvalue.rs b/src/test/ui/dst/dst-rvalue.rs new file mode 100644 index 000000000..b52a95a70 --- /dev/null +++ b/src/test/ui/dst/dst-rvalue.rs @@ -0,0 +1,12 @@ +// Check that dynamically sized rvalues are forbidden + +#![feature(box_syntax)] + +pub fn main() { + let _x: Box<str> = box *"hello world"; + //~^ ERROR E0277 + + let array: &[isize] = &[1, 2, 3]; + let _x: Box<[isize]> = box *array; + //~^ ERROR E0277 +} diff --git a/src/test/ui/dst/dst-rvalue.stderr b/src/test/ui/dst/dst-rvalue.stderr new file mode 100644 index 000000000..15830636b --- /dev/null +++ b/src/test/ui/dst/dst-rvalue.stderr @@ -0,0 +1,21 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/dst-rvalue.rs:6:28 + | +LL | let _x: Box<str> = box *"hello world"; + | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: the type of a box expression must have a statically known size + +error[E0277]: the size for values of type `[isize]` cannot be known at compilation time + --> $DIR/dst-rvalue.rs:10:32 + | +LL | let _x: Box<[isize]> = box *array; + | ^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[isize]` + = note: the type of a box expression must have a statically known size + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/dst/dst-sized-trait-param.rs b/src/test/ui/dst/dst-sized-trait-param.rs new file mode 100644 index 000000000..cfd59197b --- /dev/null +++ b/src/test/ui/dst/dst-sized-trait-param.rs @@ -0,0 +1,13 @@ +// Check that when you implement a trait that has a sized type +// parameter, the corresponding value must be sized. Also that the +// self type must be sized if appropriate. + +trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized + +impl Foo<[isize]> for usize { } +//~^ ERROR the size for values of type + +impl Foo<isize> for [usize] { } +//~^ ERROR the size for values of type + +pub fn main() { } diff --git a/src/test/ui/dst/dst-sized-trait-param.stderr b/src/test/ui/dst/dst-sized-trait-param.stderr new file mode 100644 index 000000000..8ec94f5a3 --- /dev/null +++ b/src/test/ui/dst/dst-sized-trait-param.stderr @@ -0,0 +1,33 @@ +error[E0277]: the size for values of type `[isize]` cannot be known at compilation time + --> $DIR/dst-sized-trait-param.rs:7:6 + | +LL | impl Foo<[isize]> for usize { } + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[isize]` +note: required by a bound in `Foo` + --> $DIR/dst-sized-trait-param.rs:5:11 + | +LL | trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized + | ^ required by this bound in `Foo` +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Foo<T: ?Sized> : Sized { fn take(self, x: &T) { } } // Note: T is sized + | ++++++++ + +error[E0277]: the size for values of type `[usize]` cannot be known at compilation time + --> $DIR/dst-sized-trait-param.rs:10:6 + | +LL | impl Foo<isize> for [usize] { } + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[usize]` +note: required by a bound in `Foo` + --> $DIR/dst-sized-trait-param.rs:5:16 + | +LL | trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized + | ^^^^^ required by this bound in `Foo` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. |