]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
1 | use crate::interner::HasInterner; |
2 | use crate::zip::{Zip, Zipper}; | |
3 | use crate::*; | |
4 | ||
5 | /// A fast check to see whether two things could ever possibly match. | |
6 | pub trait CouldMatch<T: ?Sized + HasInterner> { | |
7 | fn could_match(&self, interner: &T::Interner, other: &T) -> bool; | |
8 | } | |
9 | ||
10 | #[allow(unreachable_code, unused_variables)] | |
11 | impl<T, I> CouldMatch<T> for T | |
12 | where | |
13 | T: Zip<I> + ?Sized + HasInterner<Interner = I>, | |
14 | I: Interner, | |
15 | { | |
16 | fn could_match(&self, interner: &I, other: &T) -> bool { | |
17 | return Zip::zip_with(&mut MatchZipper { interner }, self, other).is_ok(); | |
18 | ||
19 | struct MatchZipper<'i, I> { | |
20 | interner: &'i I, | |
21 | }; | |
22 | ||
23 | impl<'i, I: Interner> Zipper<'i, I> for MatchZipper<'i, I> { | |
24 | fn zip_tys(&mut self, a: &Ty<I>, b: &Ty<I>) -> Fallible<()> { | |
25 | let interner = self.interner; | |
26 | let could_match = match (a.data(interner), b.data(interner)) { | |
27 | (&TyData::Apply(ref a), &TyData::Apply(ref b)) => { | |
28 | let names_could_match = a.name == b.name; | |
29 | ||
30 | names_could_match | |
31 | && a.substitution | |
32 | .iter(interner) | |
33 | .zip(b.substitution.iter(interner)) | |
34 | .all(|(p_a, p_b)| p_a.could_match(interner, &p_b)) | |
35 | } | |
36 | ||
37 | _ => true, | |
38 | }; | |
39 | ||
40 | if could_match { | |
41 | Ok(()) | |
42 | } else { | |
43 | Err(NoSolution) | |
44 | } | |
45 | } | |
46 | ||
47 | fn zip_lifetimes(&mut self, _: &Lifetime<I>, _: &Lifetime<I>) -> Fallible<()> { | |
48 | Ok(()) | |
49 | } | |
50 | ||
51 | fn zip_consts(&mut self, _: &Const<I>, _: &Const<I>) -> Fallible<()> { | |
52 | Ok(()) | |
53 | } | |
54 | ||
55 | fn zip_binders<T>(&mut self, a: &Binders<T>, b: &Binders<T>) -> Fallible<()> | |
56 | where | |
57 | T: HasInterner + Zip<I>, | |
58 | { | |
59 | Zip::zip_with(self, &a.value, &b.value) | |
60 | } | |
61 | ||
62 | fn interner(&self) -> &'i I { | |
63 | self.interner | |
64 | } | |
65 | } | |
66 | } | |
67 | } | |
68 | ||
69 | impl<I: Interner> CouldMatch<DomainGoal<I>> for ProgramClauseData<I> { | |
70 | fn could_match(&self, interner: &I, other: &DomainGoal<I>) -> bool { | |
71 | self.0.value.consequence.could_match(interner, other) | |
72 | } | |
73 | } | |
74 | ||
75 | impl<I: Interner> CouldMatch<DomainGoal<I>> for ProgramClause<I> { | |
76 | fn could_match(&self, interner: &I, other: &DomainGoal<I>) -> bool { | |
77 | self.data(interner).could_match(interner, other) | |
78 | } | |
79 | } |