// run-pass // Test that we evaluate projection predicates to winnow out // candidates during trait selection and method resolution (#20296). // If we don't properly winnow out candidates based on the output type // `Target=[A]`, then the impl marked with `(*)` is seen to conflict // with all the others. // pretty-expanded FIXME #23616 use std::marker::PhantomData; use std::ops::Deref; pub trait MyEq { fn eq(&self, u: &U) -> bool; } impl MyEq<[B]> for [A] where A : MyEq { fn eq(&self, other: &[B]) -> bool { self.len() == other.len() && self.iter().zip(other).all(|(a, b)| MyEq::eq(a, b)) } } // (*) This impl conflicts with everything unless the `Target=[A]` // constraint is considered. impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs where A: MyEq, Lhs: Deref { fn eq(&self, other: &[B; 0]) -> bool { MyEq::eq(&**self, other) } } struct DerefWithHelper { pub helper: H, pub marker: PhantomData, } trait Helper { fn helper_borrow(&self) -> &T; } impl Helper for Option { fn helper_borrow(&self) -> &T { self.as_ref().unwrap() } } impl> Deref for DerefWithHelper { type Target = T; fn deref(&self) -> &T { self.helper.helper_borrow() } } pub fn check(x: T, y: T) -> bool { let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), marker: PhantomData }; d.eq(&y) } pub fn main() { }