]>
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 | 39 | |
dfeec247 XL |
40 | fn param_env(&self) -> ty::ParamEnv<'tcx> { |
41 | self.param_env | |
42 | } | |
43 | fn a_is_expected(&self) -> bool { | |
44 | true | |
45 | } // irrelevant | |
46 | ||
47 | fn relate_with_variance<T: Relate<'tcx>>( | |
48 | &mut self, | |
49 | _: ty::Variance, | |
17df50a5 | 50 | _: ty::VarianceDiagInfo<'tcx>, |
f035d41b XL |
51 | a: T, |
52 | b: T, | |
dfeec247 | 53 | ) -> RelateResult<'tcx, T> { |
c34b1796 AL |
54 | self.relate(a, b) |
55 | } | |
56 | ||
5e7ed085 | 57 | #[instrument(skip(self), level = "debug")] |
dfeec247 XL |
58 | fn regions( |
59 | &mut self, | |
60 | a: ty::Region<'tcx>, | |
61 | b: ty::Region<'tcx>, | |
62 | ) -> RelateResult<'tcx, ty::Region<'tcx>> { | |
c34b1796 AL |
63 | Ok(a) |
64 | } | |
65 | ||
5e7ed085 | 66 | #[instrument(skip(self), level = "debug")] |
c34b1796 | 67 | fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { |
dfeec247 XL |
68 | if a == b { |
69 | return Ok(a); | |
70 | } | |
c34b1796 | 71 | |
1b1a35ee | 72 | match (a.kind(), b.kind()) { |
ba9703b0 XL |
73 | ( |
74 | _, | |
75 | &ty::Infer(ty::FreshTy(_)) | |
76 | | &ty::Infer(ty::FreshIntTy(_)) | |
77 | | &ty::Infer(ty::FreshFloatTy(_)), | |
78 | ) => Ok(a), | |
c34b1796 | 79 | |
dfeec247 | 80 | (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { |
5099ac24 | 81 | Err(TypeError::Sorts(relate::expected_found(self, a, b))) |
c34b1796 AL |
82 | } |
83 | ||
9ffffee4 | 84 | (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(self.tcx().ty_error(guar)), |
c34b1796 | 85 | |
49aad941 | 86 | _ => relate::structurally_relate_tys(self, a, b), |
c34b1796 AL |
87 | } |
88 | } | |
89 | ||
48663c56 XL |
90 | fn consts( |
91 | &mut self, | |
5099ac24 FG |
92 | a: ty::Const<'tcx>, |
93 | b: ty::Const<'tcx>, | |
94 | ) -> RelateResult<'tcx, ty::Const<'tcx>> { | |
48663c56 XL |
95 | debug!("{}.consts({:?}, {:?})", self.tag(), a, b); |
96 | if a == b { | |
97 | return Ok(a); | |
98 | } | |
99 | ||
923072b8 | 100 | match (a.kind(), b.kind()) { |
60c5eb7d | 101 | (_, ty::ConstKind::Infer(InferConst::Fresh(_))) => { |
48663c56 XL |
102 | return Ok(a); |
103 | } | |
104 | ||
60c5eb7d | 105 | (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => { |
5099ac24 | 106 | return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b))); |
48663c56 XL |
107 | } |
108 | ||
109 | _ => {} | |
110 | } | |
111 | ||
49aad941 | 112 | relate::structurally_relate_consts(self, a, b) |
48663c56 XL |
113 | } |
114 | ||
dfeec247 XL |
115 | fn binders<T>( |
116 | &mut self, | |
cdc7bbd5 XL |
117 | a: ty::Binder<'tcx, T>, |
118 | b: ty::Binder<'tcx, T>, | |
119 | ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> | |
dfeec247 XL |
120 | where |
121 | T: Relate<'tcx>, | |
c34b1796 | 122 | { |
fc512014 | 123 | Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) |
c34b1796 AL |
124 | } |
125 | } |