From dccc8db17dafa8b56bbfa1e57249845cb95cbe04 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 26 May 2023 14:06:41 +0200 Subject: [PATCH] coinductive cycle leak check test --- .../leak-check-coinductive-cycle.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs diff --git a/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs b/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs new file mode 100644 index 00000000000..1f7d4a49c90 --- /dev/null +++ b/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs @@ -0,0 +1,33 @@ +// check-pass +// compile-flags: -Ztrait-solver=next +#![feature(rustc_attrs)] + +#[rustc_coinductive] +trait Trait {} +impl<'a, 'b, T> Trait for (&'a (), &'b ()) +where + 'b: 'a, + &'a (): Trait, +{} + +impl Trait for &'static () {} +impl<'a> Trait for &'a () +where + for<'b> (&'a (), &'b ()): Trait, +{} + + +fn impls_trait, U>() {} + +fn main() { + // This infers to `impls_trait::<(&'static (), &'static ()), i32>();` + // + // In the first attempt we have 2 candidates for `&'a (): Trait<_>` + // and we get ambiguity. The result is therefore ambiguity with a `'b: 'a` + // constraint. The next attempt then uses that provisional result when + // trying to apply `impl<'a> Trait for &'a ()`. This means we get a + // `for<'b> 'b: 'a` bound which fails the leak check. Because of this we + // end up with a single impl for `&'a (): Trait<_>` which infers `_` to `i32` + // and succeeds. + impls_trait::<(&(), &()), _>(); +}