]>
Commit | Line | Data |
---|---|---|
9fa01778 XL |
1 | use crate::ty::{self, Ty, TyCtxt}; |
2 | use crate::ty::error::TypeError; | |
3 | use crate::ty::relate::{self, Relate, TypeRelation, RelateResult}; | |
c34b1796 AL |
4 | |
5 | /// A type "A" *matches* "B" if the fresh types in B could be | |
6 | /// substituted with values so as to make it equal to A. Matching is | |
7 | /// intended to be used only on freshened types, and it basically | |
8 | /// indicates if the non-freshened versions of A and B could have been | |
9 | /// unified. | |
10 | /// | |
11 | /// It is only an approximation. If it yields false, unification would | |
12 | /// definitely fail, but a true result doesn't mean unification would | |
13 | /// succeed. This is because we don't track the "side-constraints" on | |
14 | /// type variables, nor do we track if the same freshened type appears | |
15 | /// more than once. To some extent these approximations could be | |
16 | /// fixed, given effort. | |
17 | /// | |
18 | /// Like subtyping, matching is really a binary relation, so the only | |
19 | /// important thing about the result is Ok/Err. Also, matching never | |
20 | /// affects any type variables or unification state. | |
a7813a04 XL |
21 | pub struct Match<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { |
22 | tcx: TyCtxt<'a, 'gcx, 'tcx> | |
c34b1796 AL |
23 | } |
24 | ||
a7813a04 XL |
25 | impl<'a, 'gcx, 'tcx> Match<'a, 'gcx, 'tcx> { |
26 | pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Match<'a, 'gcx, 'tcx> { | |
a1dfa0c6 | 27 | Match { tcx } |
c34b1796 AL |
28 | } |
29 | } | |
30 | ||
a7813a04 | 31 | impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> { |
c34b1796 | 32 | fn tag(&self) -> &'static str { "Match" } |
a7813a04 | 33 | fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.tcx } |
c34b1796 AL |
34 | fn a_is_expected(&self) -> bool { true } // irrelevant |
35 | ||
a7813a04 XL |
36 | fn relate_with_variance<T: Relate<'tcx>>(&mut self, |
37 | _: ty::Variance, | |
38 | a: &T, | |
39 | b: &T) | |
40 | -> RelateResult<'tcx, T> | |
c34b1796 AL |
41 | { |
42 | self.relate(a, b) | |
43 | } | |
44 | ||
7cac9316 XL |
45 | fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) |
46 | -> RelateResult<'tcx, ty::Region<'tcx>> { | |
62682a34 | 47 | debug!("{}.regions({:?}, {:?})", |
c34b1796 | 48 | self.tag(), |
62682a34 SL |
49 | a, |
50 | b); | |
c34b1796 AL |
51 | Ok(a) |
52 | } | |
53 | ||
54 | fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { | |
62682a34 SL |
55 | debug!("{}.tys({:?}, {:?})", self.tag(), |
56 | a, b); | |
c34b1796 AL |
57 | if a == b { return Ok(a); } |
58 | ||
59 | match (&a.sty, &b.sty) { | |
b7449926 XL |
60 | (_, &ty::Infer(ty::FreshTy(_))) | |
61 | (_, &ty::Infer(ty::FreshIntTy(_))) | | |
62 | (_, &ty::Infer(ty::FreshFloatTy(_))) => { | |
c34b1796 AL |
63 | Ok(a) |
64 | } | |
65 | ||
b7449926 XL |
66 | (&ty::Infer(_), _) | |
67 | (_, &ty::Infer(_)) => { | |
e9174d1e | 68 | Err(TypeError::Sorts(relate::expected_found(self, &a, &b))) |
c34b1796 AL |
69 | } |
70 | ||
b7449926 | 71 | (&ty::Error, _) | (_, &ty::Error) => { |
c34b1796 AL |
72 | Ok(self.tcx().types.err) |
73 | } | |
74 | ||
75 | _ => { | |
e9174d1e | 76 | relate::super_relate_tys(self, a, b) |
c34b1796 AL |
77 | } |
78 | } | |
79 | } | |
80 | ||
81 | fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>) | |
82 | -> RelateResult<'tcx, ty::Binder<T>> | |
a7813a04 | 83 | where T: Relate<'tcx> |
c34b1796 | 84 | { |
83c7162d | 85 | Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) |
c34b1796 AL |
86 | } |
87 | } |