]>
Commit | Line | Data |
---|---|---|
9fa01778 | 1 | use crate::ty::error::TypeError; |
dfeec247 XL |
2 | use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; |
3 | use crate::ty::{self, InferConst, Ty, TyCtxt}; | |
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. | |
dc9dc135 XL |
21 | pub struct Match<'tcx> { |
22 | tcx: TyCtxt<'tcx>, | |
416331ca | 23 | param_env: ty::ParamEnv<'tcx>, |
c34b1796 AL |
24 | } |
25 | ||
a2a8927a | 26 | impl<'tcx> Match<'tcx> { |
416331ca XL |
27 | pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> { |
28 | Match { tcx, param_env } | |
c34b1796 AL |
29 | } |
30 | } | |
31 | ||
a2a8927a | 32 | impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { |
dfeec247 XL |
33 | fn tag(&self) -> &'static str { |
34 | "Match" | |
35 | } | |
36 | fn tcx(&self) -> TyCtxt<'tcx> { | |
37 | self.tcx | |
38 | } | |
487cf647 FG |
39 | |
40 | fn intercrate(&self) -> bool { | |
41 | false | |
42 | } | |
43 | ||
dfeec247 XL |
44 | fn param_env(&self) -> ty::ParamEnv<'tcx> { |
45 | self.param_env | |
46 | } | |
47 | fn a_is_expected(&self) -> bool { | |
48 | true | |
49 | } // irrelevant | |
50 | ||
487cf647 FG |
51 | fn mark_ambiguous(&mut self) { |
52 | bug!() | |
53 | } | |
54 | ||
dfeec247 XL |
55 | fn relate_with_variance<T: Relate<'tcx>>( |
56 | &mut self, | |
57 | _: ty::Variance, | |
17df50a5 | 58 | _: ty::VarianceDiagInfo<'tcx>, |
f035d41b XL |
59 | a: T, |
60 | b: T, | |
dfeec247 | 61 | ) -> RelateResult<'tcx, T> { |
c34b1796 AL |
62 | self.relate(a, b) |
63 | } | |
64 | ||
5e7ed085 | 65 | #[instrument(skip(self), level = "debug")] |
dfeec247 XL |
66 | fn regions( |
67 | &mut self, | |
68 | a: ty::Region<'tcx>, | |
69 | b: ty::Region<'tcx>, | |
70 | ) -> RelateResult<'tcx, ty::Region<'tcx>> { | |
c34b1796 AL |
71 | Ok(a) |
72 | } | |
73 | ||
5e7ed085 | 74 | #[instrument(skip(self), level = "debug")] |
c34b1796 | 75 | fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { |
dfeec247 XL |
76 | if a == b { |
77 | return Ok(a); | |
78 | } | |
c34b1796 | 79 | |
1b1a35ee | 80 | match (a.kind(), b.kind()) { |
ba9703b0 XL |
81 | ( |
82 | _, | |
83 | &ty::Infer(ty::FreshTy(_)) | |
84 | | &ty::Infer(ty::FreshIntTy(_)) | |
85 | | &ty::Infer(ty::FreshFloatTy(_)), | |
86 | ) => Ok(a), | |
c34b1796 | 87 | |
dfeec247 | 88 | (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { |
5099ac24 | 89 | Err(TypeError::Sorts(relate::expected_found(self, a, b))) |
c34b1796 AL |
90 | } |
91 | ||
f035d41b | 92 | (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()), |
c34b1796 | 93 | |
dfeec247 | 94 | _ => relate::super_relate_tys(self, a, b), |
c34b1796 AL |
95 | } |
96 | } | |
97 | ||
48663c56 XL |
98 | fn consts( |
99 | &mut self, | |
5099ac24 FG |
100 | a: ty::Const<'tcx>, |
101 | b: ty::Const<'tcx>, | |
102 | ) -> RelateResult<'tcx, ty::Const<'tcx>> { | |
48663c56 XL |
103 | debug!("{}.consts({:?}, {:?})", self.tag(), a, b); |
104 | if a == b { | |
105 | return Ok(a); | |
106 | } | |
107 | ||
923072b8 | 108 | match (a.kind(), b.kind()) { |
60c5eb7d | 109 | (_, ty::ConstKind::Infer(InferConst::Fresh(_))) => { |
48663c56 XL |
110 | return Ok(a); |
111 | } | |
112 | ||
60c5eb7d | 113 | (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => { |
5099ac24 | 114 | return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b))); |
48663c56 XL |
115 | } |
116 | ||
117 | _ => {} | |
118 | } | |
119 | ||
120 | relate::super_relate_consts(self, a, b) | |
121 | } | |
122 | ||
dfeec247 XL |
123 | fn binders<T>( |
124 | &mut self, | |
cdc7bbd5 XL |
125 | a: ty::Binder<'tcx, T>, |
126 | b: ty::Binder<'tcx, T>, | |
127 | ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> | |
dfeec247 XL |
128 | where |
129 | T: Relate<'tcx>, | |
c34b1796 | 130 | { |
fc512014 | 131 | Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) |
c34b1796 AL |
132 | } |
133 | } |