1 // run-pass
2 // Test that we evaluate projection predicates to winnow out
3 // candidates during trait selection and method resolution (#20296).
4 // If we don't properly winnow out candidates based on the output type
5 // `Target=[A]`, then the impl marked with `(*)` is seen to conflict
6 // with all the others.
7
8 // pretty-expanded FIXME #23616
9
10 use std::marker::PhantomData;
11 use std::ops::Deref;
12
13 pub trait MyEq<U: ?Sized=Self> {
eq(&self, u: &U) -> bool14 fn eq(&self, u: &U) -> bool;
15 }
16
17 impl<A, B> MyEq<[B]> for [A]
18 where A : MyEq<B>
19 {
eq(&self, other: &[B]) -> bool20 fn eq(&self, other: &[B]) -> bool {
21 self.len() == other.len() &&
22 self.iter().zip(other).all(|(a, b)| MyEq::eq(a, b))
23 }
24 }
25
26 // (*) This impl conflicts with everything unless the `Target=[A]`
27 // constraint is considered.
28 impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs
29 where A: MyEq<B>, Lhs: Deref<Target=[A]>
30 {
eq(&self, other: &[B; 0]) -> bool31 fn eq(&self, other: &[B; 0]) -> bool {
32 MyEq::eq(&**self, other)
33 }
34 }
35
36 struct DerefWithHelper<H, T> {
37 pub helper: H,
38 pub marker: PhantomData<T>,
39 }
40
41 trait Helper<T> {
helper_borrow(&self) -> &T42 fn helper_borrow(&self) -> &T;
43 }
44
45 impl<T> Helper<T> for Option<T> {
helper_borrow(&self) -> &T46 fn helper_borrow(&self) -> &T {
47 self.as_ref().unwrap()
48 }
49 }
50
51 impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
52 type Target = T;
53
deref(&self) -> &T54 fn deref(&self) -> &T {
55 self.helper.helper_borrow()
56 }
57 }
58
check<T: MyEq>(x: T, y: T) -> bool59 pub fn check<T: MyEq>(x: T, y: T) -> bool {
60 let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x),
61 marker: PhantomData };
62 d.eq(&y)
63 }
64
main()65 pub fn main() {
66 }
67