about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2020-07-05 12:16:25 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2020-10-06 11:19:31 +0100
commitf52b2d88903036beb0533b04011064575b3abd36 (patch)
tree492c032bb0cbb8b725d7b514488373b5b54030f1 /src
parent582ccec1c577eedf6394078e93366714273f922b (diff)
downloadrust-f52b2d88903036beb0533b04011064575b3abd36.tar.gz
rust-f52b2d88903036beb0533b04011064575b3abd36.zip
Avoid cycle in nested obligations for object candidate
Bounds of the form `type Future: Future<Result=Self::Result>` exist in
some ecosystem crates. To validate these bounds for trait objects we
need to normalize `Self::Result` in a way that doesn't cause a cycle.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-4.rs17
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-4.stderr12
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-5.rs27
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-5.stderr12
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-6.rs24
-rw-r--r--src/test/ui/traits/check-trait-object-bounds-6.stderr12
-rw-r--r--src/test/ui/traits/trait-object-bounds-cycle-1.rs24
-rw-r--r--src/test/ui/traits/trait-object-bounds-cycle-2.rs28
-rw-r--r--src/test/ui/traits/trait-object-bounds-cycle-3.rs25
-rw-r--r--src/test/ui/traits/trait-object-bounds-cycle-4.rs25
10 files changed, 206 insertions, 0 deletions
diff --git a/src/test/ui/traits/check-trait-object-bounds-4.rs b/src/test/ui/traits/check-trait-object-bounds-4.rs
new file mode 100644
index 00000000000..323508db2f2
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-4.rs
@@ -0,0 +1,17 @@
+// Check that we validate associated type bounds on super traits for trait
+// objects
+
+trait Super {
+    type Y: Clone;
+}
+
+trait X: Super {}
+
+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-4.stderr b/src/test/ui/traits/check-trait-object-bounds-4.stderr
new file mode 100644
index 00000000000..75d6862579d
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-4.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `str: std::clone::Clone` is not satisfied
+  --> $DIR/check-trait-object-bounds-4.rs:15: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-5.rs b/src/test/ui/traits/check-trait-object-bounds-5.rs
new file mode 100644
index 00000000000..7d733ad26b7
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-5.rs
@@ -0,0 +1,27 @@
+// Check that we validate associated type bounds on super traits for trait
+// objects
+
+trait Is {
+    type T;
+}
+
+impl<U> Is for U {
+    type T = U;
+}
+
+trait Super {
+    type V;
+}
+
+trait Obj: Super {
+    type U: Is<T = Self::V>;
+}
+
+fn is_obj<T: ?Sized + Obj>(_: &T) {}
+
+fn f(x: &dyn Obj<U = i32, V = i64>) {
+    is_obj(x)
+    //~^ type mismatch resolving `<i32 as Is>::T == i64`
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/check-trait-object-bounds-5.stderr b/src/test/ui/traits/check-trait-object-bounds-5.stderr
new file mode 100644
index 00000000000..bd2b789cd99
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-5.stderr
@@ -0,0 +1,12 @@
+error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
+  --> $DIR/check-trait-object-bounds-5.rs:23:5
+   |
+LL | fn is_obj<T: ?Sized + Obj>(_: &T) {}
+   |                       --- required by this bound in `is_obj`
+...
+LL |     is_obj(x)
+   |     ^^^^^^ expected `i64`, found `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/traits/check-trait-object-bounds-6.rs b/src/test/ui/traits/check-trait-object-bounds-6.rs
new file mode 100644
index 00000000000..cb196d67f67
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-6.rs
@@ -0,0 +1,24 @@
+// Check that we validate associated type bounds on super traits for trait
+// objects
+
+trait Is {
+    type T;
+}
+
+impl<U> Is for U {
+    type T = U;
+}
+
+trait Obj {
+    type U: Is<T = Self::V>;
+    type V;
+}
+
+fn is_obj<T: ?Sized + Obj>(_: &T) {}
+
+fn f(x: &dyn Obj<U = i32, V = i64>) {
+    is_obj(x)
+    //~^ ERROR type mismatch resolving `<i32 as Is>::T == i64`
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/check-trait-object-bounds-6.stderr b/src/test/ui/traits/check-trait-object-bounds-6.stderr
new file mode 100644
index 00000000000..ea1fdaf46f6
--- /dev/null
+++ b/src/test/ui/traits/check-trait-object-bounds-6.stderr
@@ -0,0 +1,12 @@
+error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
+  --> $DIR/check-trait-object-bounds-6.rs:20:5
+   |
+LL | fn is_obj<T: ?Sized + Obj>(_: &T) {}
+   |                       --- required by this bound in `is_obj`
+...
+LL |     is_obj(x)
+   |     ^^^^^^ expected `i64`, found `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/traits/trait-object-bounds-cycle-1.rs b/src/test/ui/traits/trait-object-bounds-cycle-1.rs
new file mode 100644
index 00000000000..3146764927c
--- /dev/null
+++ b/src/test/ui/traits/trait-object-bounds-cycle-1.rs
@@ -0,0 +1,24 @@
+// Check that we don't have a cycle when we try to normalize `Self::U` in the
+// bound below.
+
+// check-pass
+
+trait Is {
+    type T;
+}
+
+impl<U> Is for U {
+    type T = U;
+}
+
+trait Obj {
+    type U: Is<T = Self::U>;
+}
+
+fn is_obj<T: ?Sized + Obj>(_: &T) {}
+
+fn f(x: &dyn Obj<U = i32>) {
+    is_obj(x)
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/trait-object-bounds-cycle-2.rs b/src/test/ui/traits/trait-object-bounds-cycle-2.rs
new file mode 100644
index 00000000000..4c1df38058d
--- /dev/null
+++ b/src/test/ui/traits/trait-object-bounds-cycle-2.rs
@@ -0,0 +1,28 @@
+// Check that we don't have a cycle when we try to normalize `Self::V` in the
+// bound below.
+
+// check-pass
+
+trait Is {
+    type T;
+}
+
+impl<U> Is for U {
+    type T = U;
+}
+
+trait Super {
+    type V;
+}
+
+trait Obj: Super {
+    type U: Is<T = Self::V>;
+}
+
+fn is_obj<T: ?Sized + Obj>(_: &T) {}
+
+fn f(x: &dyn Obj<U = i32, V = i32>) {
+    is_obj(x)
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/trait-object-bounds-cycle-3.rs b/src/test/ui/traits/trait-object-bounds-cycle-3.rs
new file mode 100644
index 00000000000..55726a5ae45
--- /dev/null
+++ b/src/test/ui/traits/trait-object-bounds-cycle-3.rs
@@ -0,0 +1,25 @@
+// Check that we don't have a cycle when we try to normalize `Self::V` in the
+// bound below.
+
+// check-pass
+
+trait Is {
+    type T;
+}
+
+impl<U> Is for U {
+    type T = U;
+}
+
+trait Obj {
+    type U: Is<T = Self::V>;
+    type V;
+}
+
+fn is_obj<T: ?Sized + Obj>(_: &T) {}
+
+fn f(x: &dyn Obj<U = i32, V = i32>) {
+    is_obj(x)
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/trait-object-bounds-cycle-4.rs b/src/test/ui/traits/trait-object-bounds-cycle-4.rs
new file mode 100644
index 00000000000..f83cb75c7f2
--- /dev/null
+++ b/src/test/ui/traits/trait-object-bounds-cycle-4.rs
@@ -0,0 +1,25 @@
+// Check that we don't have a cycle when we try to normalize `Self::U` in the
+// bound below. Make sure that having a lifetime on the trait object doesn't break things
+
+// check-pass
+
+trait Is {
+    type T;
+}
+
+impl<U> Is for U {
+    type T = U;
+}
+
+trait Obj<'a> {
+    type U: Is<T = Self::V>;
+    type V;
+}
+
+fn is_obj<'a, T: ?Sized + Obj<'a>>(_: &T) {}
+
+fn f<'a>(x: &dyn Obj<'a, U = i32, V = i32>) {
+    is_obj(x)
+}
+
+fn main() {}