// compile-flags: -Znext-solver #![feature(rustc_attrs)] // Check that we correctly rerun the trait solver for heads of cycles, // even if they are not the root. struct A(*const T); struct B(*const T); struct C(*const T); #[rustc_coinductive] trait Trait<'a, 'b> {} trait NotImplemented {} impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for A where B: Trait<'a, 'b> {} // With this the root of `B` is `A`, even if the other impl does // not have a cycle with `A`. This candidate never applies because of // the `A: NotImplemented` bound. impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B where A: Trait<'a, 'b>, A: NotImplemented, { } // This impl directly requires 'b to be equal to 'static. // // Because of the coinductive cycle through `C` it also requires // 'a to be 'static. impl<'a, T: ?Sized> Trait<'a, 'static> for B where C: Trait<'a, 'a>, {} // In the first iteration of `B: Trait<'a, 'b>` we don't add any // constraints here, only after setting the provisional result to require // `'b == 'static` do we also add that constraint for `'a`. impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for C where B: Trait<'a, 'b>, {} fn impls_trait<'a, 'b, T: Trait<'a, 'b> + ?Sized>() {} fn check<'a, T: ?Sized>() { impls_trait::<'a, 'static, A>(); //~^ ERROR lifetime may not live long enough } fn main() { check::<()>(); }