]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/_match.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / _match.rs
CommitLineData
9fa01778 1use crate::ty::error::TypeError;
dfeec247
XL
2use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
3use 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
21pub struct Match<'tcx> {
22 tcx: TyCtxt<'tcx>,
416331ca 23 param_env: ty::ParamEnv<'tcx>,
c34b1796
AL
24}
25
a2a8927a 26impl<'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 32impl<'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}