// Test a case where variance and higher-ranked types interact in surprising ways. // // In particular, we test this pattern in trait solving, where it is not connected // to any part of the source code. trait Trait {} fn foo() where T: Trait fn(fn(&'b u32))>, { } impl<'a> Trait for () {} fn main() { // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: // // - The impl provides the clause `forall<'a> { (): Trait }` // - We instantiate `'a` existentially to get `(): Trait` // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a // "bidirectional" equality check, so we wind up with: // - `fn(fn(&?a u32)) == for<'b> fn(fn(&'b u32))` :- // - `fn(&!b u32) == fn(&?a u32)` // - `&?a u32 == &!b u32` // - `?a == !b` -- error. // - `fn(fn(&?a u32)) == for<'b> fn(fn(&'b u32))` :- // - `fn(&?b u32) == fn(&?a u32)` // - `&?a u32 == &?b u32` // - `?a == ?b` -- OK. // - So the unification fails. foo::<()>(); //~^ ERROR implementation of `Trait` is not general enough }