| // 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<U: ?Sized=Self> { |
| fn eq(&self, u: &U) -> bool; |
| } |
| |
| impl<A, B> MyEq<[B]> for [A] |
| where A : MyEq<B> |
| { |
| 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<B>, Lhs: Deref<Target=[A]> |
| { |
| fn eq(&self, other: &[B; 0]) -> bool { |
| MyEq::eq(&**self, other) |
| } |
| } |
| |
| struct DerefWithHelper<H, T> { |
| pub helper: H, |
| pub marker: PhantomData<T>, |
| } |
| |
| trait Helper<T> { |
| fn helper_borrow(&self) -> &T; |
| } |
| |
| impl<T> Helper<T> for Option<T> { |
| fn helper_borrow(&self) -> &T { |
| self.as_ref().unwrap() |
| } |
| } |
| |
| impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> { |
| type Target = T; |
| |
| fn deref(&self) -> &T { |
| self.helper.helper_borrow() |
| } |
| } |
| |
| pub fn check<T: MyEq>(x: T, y: T) -> bool { |
| let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x), |
| marker: PhantomData }; |
| d.eq(&y) |
| } |
| |
| pub fn main() { |
| } |