//@ check-pass // This test checks that we're correctly dealing with inductive cycles // with canonical inference variables. trait Trait {} trait IsNotU32 {} impl IsNotU32 for i32 {} impl Trait for () // impl 1 where (): Trait {} impl Trait for () {} // impl 2 // If we now check whether `(): Trait` holds this has to // result in ambiguity as both `for (): Trait` and `(): Trait` // 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 // - impl 1 // - ?0: IsNotU32 // ambig // - (): Trait // canonical cycle -> err // - ERR // - impl 2 // - OK ?0 == u32 // // Result: OK ?0 == u32. // (): Trait // - impl 1 // - i32: IsNotU32 // ok // - (): Trait // - impl 1 // - u32: IsNotU32 // err // - ERR // - impl 2 // - OK // - OK // - impl 2 (trivial ERR) // // Result OK // This would mean that `(): Trait` is not complete, // which is unsound if we're in coherence. fn implements_trait() -> (T, U) where (): Trait, { todo!() } // A hack to only constrain the infer vars after first checking // the `(): Trait<_, _>`. trait Constrain {} impl Constrain for T {} fn constrain, U>(_: U) {} fn main() { let (x, y) = implements_trait::<_, _>(); constrain::(x); constrain::(y); }