]> git.proxmox.com Git - rustc.git/blame - vendor/chalk-ir-0.14.0/src/could_match.rs
New upstream version 1.47.0+dfsg1
[rustc.git] / vendor / chalk-ir-0.14.0 / src / could_match.rs
CommitLineData
f035d41b
XL
1use crate::interner::HasInterner;
2use crate::zip::{Zip, Zipper};
3use crate::*;
4
5/// A fast check to see whether two things could ever possibly match.
6pub trait CouldMatch<T: ?Sized + HasInterner> {
7 fn could_match(&self, interner: &T::Interner, other: &T) -> bool;
8}
9
10#[allow(unreachable_code, unused_variables)]
11impl<T, I> CouldMatch<T> for T
12where
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
69impl<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
75impl<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}