summaryrefslogtreecommitdiffstats
path: root/src/test/ui/dst
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/dst
parentInitial commit. (diff)
downloadrustc-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')
-rw-r--r--src/test/ui/dst/dst-bad-assign-2.rs38
-rw-r--r--src/test/ui/dst/dst-bad-assign-2.stderr12
-rw-r--r--src/test/ui/dst/dst-bad-assign-3.rs39
-rw-r--r--src/test/ui/dst/dst-bad-assign-3.stderr24
-rw-r--r--src/test/ui/dst/dst-bad-assign.rs41
-rw-r--r--src/test/ui/dst/dst-bad-assign.stderr24
-rw-r--r--src/test/ui/dst/dst-bad-coerce1.rs36
-rw-r--r--src/test/ui/dst/dst-bad-coerce1.stderr42
-rw-r--r--src/test/ui/dst/dst-bad-coerce2.rs31
-rw-r--r--src/test/ui/dst/dst-bad-coerce2.stderr47
-rw-r--r--src/test/ui/dst/dst-bad-coerce3.rs37
-rw-r--r--src/test/ui/dst/dst-bad-coerce3.stderr58
-rw-r--r--src/test/ui/dst/dst-bad-coerce4.rs25
-rw-r--r--src/test/ui/dst/dst-bad-coerce4.stderr25
-rw-r--r--src/test/ui/dst/dst-bad-coercions.rs26
-rw-r--r--src/test/ui/dst/dst-bad-coercions.stderr80
-rw-r--r--src/test/ui/dst/dst-bad-deep-2.rs13
-rw-r--r--src/test/ui/dst/dst-bad-deep-2.stderr14
-rw-r--r--src/test/ui/dst/dst-bad-deep.rs15
-rw-r--r--src/test/ui/dst/dst-bad-deep.stderr17
-rw-r--r--src/test/ui/dst/dst-index.rs37
-rw-r--r--src/test/ui/dst/dst-index.stderr28
-rw-r--r--src/test/ui/dst/dst-object-from-unsized-type.rs27
-rw-r--r--src/test/ui/dst/dst-object-from-unsized-type.stderr51
-rw-r--r--src/test/ui/dst/dst-rvalue.rs12
-rw-r--r--src/test/ui/dst/dst-rvalue.stderr21
-rw-r--r--src/test/ui/dst/dst-sized-trait-param.rs13
-rw-r--r--src/test/ui/dst/dst-sized-trait-param.stderr33
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`.