summaryrefslogtreecommitdiffstats
path: root/src/test/ui/associated-types/associated-types-conditional-dispatch.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/associated-types/associated-types-conditional-dispatch.rs')
-rw-r--r--src/test/ui/associated-types/associated-types-conditional-dispatch.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/test/ui/associated-types/associated-types-conditional-dispatch.rs b/src/test/ui/associated-types/associated-types-conditional-dispatch.rs
new file mode 100644
index 000000000..70ee60517
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-conditional-dispatch.rs
@@ -0,0 +1,66 @@
+// 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() {
+}