diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/traits/solver-cycles | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/traits/solver-cycles')
-rw-r--r-- | tests/ui/traits/solver-cycles/inductive-canonical-cycle.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/tests/ui/traits/solver-cycles/inductive-canonical-cycle.rs b/tests/ui/traits/solver-cycles/inductive-canonical-cycle.rs new file mode 100644 index 000000000..5449f5f00 --- /dev/null +++ b/tests/ui/traits/solver-cycles/inductive-canonical-cycle.rs @@ -0,0 +1,69 @@ +// check-pass + +// This test checks that we're correctly dealing with inductive cycles +// with canonical inference variables. + +trait Trait<T, U> {} + +trait IsNotU32 {} +impl IsNotU32 for i32 {} +impl<T: IsNotU32, U> Trait<T, U> for () // impl 1 +where + (): Trait<U, T> +{} + +impl<T> Trait<u32, T> for () {} // impl 2 + +// If we now check whether `(): Trait<?0, ?1>` holds this has to +// result in ambiguity as both `for<T> (): Trait<u32, T>` and `(): Trait<i32, u32>` +// applies. The remainder of this test asserts that. + +// If we were to error on inductive cycles with canonical inference variables +// this would be wrong: + +// (): Trait<?0, ?1> +// - impl 1 +// - ?0: IsNotU32 // ambig +// - (): Trait<?1, ?0> // canonical cycle -> err +// - ERR +// - impl 2 +// - OK ?0 == u32 +// +// Result: OK ?0 == u32. + +// (): Trait<i32, u32> +// - impl 1 +// - i32: IsNotU32 // ok +// - (): Trait<u32, i32> +// - impl 1 +// - u32: IsNotU32 // err +// - ERR +// - impl 2 +// - OK +// - OK +// - impl 2 (trivial ERR) +// +// Result OK + +// This would mean that `(): Trait<?0, ?1>` is not complete, +// which is unsound if we're in coherence. + +fn implements_trait<T, U>() -> (T, U) +where + (): Trait<T, U>, +{ + todo!() +} + +// A hack to only constrain the infer vars after first checking +// the `(): Trait<_, _>`. +trait Constrain<T> {} +impl<T> Constrain<T> for T {} +fn constrain<T: Constrain<U>, U>(_: U) {} + +fn main() { + let (x, y) = implements_trait::<_, _>(); + + constrain::<i32, _>(x); + constrain::<u32, _>(y); +} |