diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2020-07-05 12:16:25 +0100 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2020-10-06 11:19:31 +0100 |
| commit | f52b2d88903036beb0533b04011064575b3abd36 (patch) | |
| tree | 492c032bb0cbb8b725d7b514488373b5b54030f1 /src | |
| parent | 582ccec1c577eedf6394078e93366714273f922b (diff) | |
| download | rust-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.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/traits/check-trait-object-bounds-4.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/traits/check-trait-object-bounds-5.rs | 27 | ||||
| -rw-r--r-- | src/test/ui/traits/check-trait-object-bounds-5.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/traits/check-trait-object-bounds-6.rs | 24 | ||||
| -rw-r--r-- | src/test/ui/traits/check-trait-object-bounds-6.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-object-bounds-cycle-1.rs | 24 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-object-bounds-cycle-2.rs | 28 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-object-bounds-cycle-3.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/traits/trait-object-bounds-cycle-4.rs | 25 |
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() {} |
