about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2020-06-28 20:34:56 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2020-10-06 11:19:30 +0100
commit2bdf723da7c465e052a1b1fc448c0014c46b9e51 (patch)
tree7a8bec8c03d6787d713f912f59e9e7db9da699af /src
parent0a76584dcc6dd6ae8f32f905dde379a99da7e516 (diff)
downloadrust-2bdf723da7c465e052a1b1fc448c0014c46b9e51.tar.gz
rust-2bdf723da7c465e052a1b1fc448c0014c46b9e51.zip
Ensure that associated types for trait objects satisfy their bounds
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/issues/issue-41139.rs4
-rw-r--r--src/test/ui/issues/issue-41139.stderr13
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-1.rs14
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-1.stderr12
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-2-ok.rs15
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-2.rs15
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-2.stderr14
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-3.rs21
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-3.stderr12
9 files changed, 115 insertions, 5 deletions
diff --git a/src/test/ui/issues/issue-41139.rs b/src/test/ui/issues/issue-41139.rs
index 4814232607c..ebdc5cb6dbe 100644
--- a/src/test/ui/issues/issue-41139.rs
+++ b/src/test/ui/issues/issue-41139.rs
@@ -3,6 +3,8 @@ trait Trait {}
 fn get_function<'a>() -> &'a dyn Fn() -> dyn Trait { panic!("") }
 
 fn main() {
+    // This isn't great. The issue here is that `dyn Trait` is not sized, so
+    // `dyn Fn() -> dyn Trait` is not well-formed.
     let t : &dyn Trait = &get_function()();
-    //~^ ERROR cannot move a value of type dyn Trait
+    //~^ ERROR expected function, found `&dyn std::ops::Fn() -> (dyn Trait + 'static)`
 }
diff --git a/src/test/ui/issues/issue-41139.stderr b/src/test/ui/issues/issue-41139.stderr
index 829d0cfa72c..083c413c316 100644
--- a/src/test/ui/issues/issue-41139.stderr
+++ b/src/test/ui/issues/issue-41139.stderr
@@ -1,9 +1,14 @@
-error[E0161]: cannot move a value of type dyn Trait: the size of dyn Trait cannot be statically determined
-  --> $DIR/issue-41139.rs:6:27
+error[E0618]: expected function, found `&dyn std::ops::Fn() -> (dyn Trait + 'static)`
+  --> $DIR/issue-41139.rs:8:27
    |
+LL | fn get_function<'a>() -> &'a dyn Fn() -> dyn Trait { panic!("") }
+   | ----------------------------------------------------------------- `get_function` defined here returns `&dyn std::ops::Fn() -> (dyn Trait + 'static)`
+...
 LL |     let t : &dyn Trait = &get_function()();
-   |                           ^^^^^^^^^^^^^^^^
+   |                           ^^^^^^^^^^^^^^--
+   |                           |
+   |                           call expression requires function
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0161`.
+For more information about this error, try `rustc --explain E0618`.
diff --git a/src/test/ui/traits/check-trait-object-bounds-1.rs b/src/test/ui/traits/check-trait-object-bounds-1.rs
new file mode 100644
index 00000000000..ad908a750b4
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-1.rs
@@ -0,0 +1,14 @@
+// Check that we validate associated type bounds for trait objects
+
+trait X {
+    type Y: Clone;
+}
+
+fn f<T: X + ?Sized>() {
+    None::<T::Y>.clone();
+}
+
+fn main() {
+    f::<dyn X<Y = str>>();
+    //~^ ERROR the trait bound `str: std::clone::Clone` is not satisfied
+}
diff --git a/src/test/ui/traits/check-trait-object-bounds-1.stderr b/src/test/ui/traits/check-trait-object-bounds-1.stderr
new file mode 100644
index 00000000000..c53c91d42a7
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-1.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `str: std::clone::Clone` is not satisfied
+  --> $DIR/check-trait-object-bounds-1.rs:12:5
+   |
+LL | fn f<T: X + ?Sized>() {
+   |         - required by this bound in `f`
+...
+LL |     f::<dyn X<Y = str>>();
+   |     ^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/check-trait-object-bounds-2-ok.rs b/src/test/ui/traits/check-trait-object-bounds-2-ok.rs
new file mode 100644
index 00000000000..1422dda276b
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-2-ok.rs
@@ -0,0 +1,15 @@
+// Make sure that we're handling bound lifetimes correctly when validating trait
+// bounds.
+// run-pass
+
+trait X<'a> {
+    type F: FnOnce(&i32) -> &'a i32;
+}
+
+fn f<T: for<'r> X<'r> + ?Sized>() {
+    None::<T::F>.map(|f| f(&0));
+}
+
+fn main() {
+    f::<dyn for<'x> X<'x, F = fn(&i32) -> &'x i32>>();
+}
diff --git a/src/test/ui/traits/check-trait-object-bounds-2.rs b/src/test/ui/traits/check-trait-object-bounds-2.rs
new file mode 100644
index 00000000000..f825008c6a2
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-2.rs
@@ -0,0 +1,15 @@
+// Check that we validate associated type bounds for trait objects when they
+// have bound lifetimes
+
+trait X<'a> {
+    type F: FnOnce(&i32) -> &'a i32;
+}
+
+fn f<T: for<'r> X<'r> + ?Sized>() {
+    None::<T::F>.map(|f| f(&0));
+}
+
+fn main() {
+    f::<dyn for<'x> X<'x, F = i32>>();
+    //~^ expected a `std::ops::FnOnce<(&i32,)>` closure, found `i32`
+}
diff --git a/src/test/ui/traits/check-trait-object-bounds-2.stderr b/src/test/ui/traits/check-trait-object-bounds-2.stderr
new file mode 100644
index 00000000000..1241fc8cb51
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-2.stderr
@@ -0,0 +1,14 @@
+error[E0277]: expected a `std::ops::FnOnce<(&i32,)>` closure, found `i32`
+  --> $DIR/check-trait-object-bounds-2.rs:13:5
+   |
+LL | fn f<T: for<'r> X<'r> + ?Sized>() {
+   |         ------------- required by this bound in `f`
+...
+LL |     f::<dyn for<'x> X<'x, F = i32>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `i32`
+   |
+   = help: the trait `for<'r> std::ops::FnOnce<(&'r i32,)>` is not implemented for `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/check-trait-object-bounds-3.rs b/src/test/ui/traits/check-trait-object-bounds-3.rs
new file mode 100644
index 00000000000..d05aa14f2cf
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-3.rs
@@ -0,0 +1,21 @@
+// Check that we validate associated type bounds for trait objects
+
+trait X<'a> {
+    type Y: Into<&'static str> + From<&'a str>;
+}
+
+fn f<'a, T: X<'a> + ?Sized>(s: &'a str) -> &'static str {
+    T::Y::from(s).into()
+}
+
+pub fn main() {
+    let z;
+    {
+        let s = String::from("abcdef");
+        z = f::<dyn X<Y = &str>>(&s);
+        //~^ ERROR `s` does not live long enough
+    }
+
+    println!("{}", z)
+}
+
diff --git a/src/test/ui/traits/check-trait-object-bounds-3.stderr b/src/test/ui/traits/check-trait-object-bounds-3.stderr
new file mode 100644
index 00000000000..e2a4341454a
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-3.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `str: std::clone::Clone` is not satisfied
+  --> $DIR/check-trait-object-bounds-3.rs:12:5
+   |
+LL | fn f<T: X + ?Sized>() {
+   |         - required by this bound in `f`
+...
+LL |     f::<dyn X<Y = str>>();
+   |     ^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.