rustc_infer/infer/
context.rs

1///! Definition of `InferCtxtLike` from the librarified type layer.
2use rustc_hir::def_id::DefId;
3use rustc_middle::traits::ObligationCause;
4use rustc_middle::ty::relate::RelateResult;
5use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
6use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
7use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
8
9use super::{
10    BoundRegionConversionTime, InferCtxt, OpaqueTypeStorageEntries, RegionVariableOrigin,
11    SubregionOrigin,
12};
13
14impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
15    type Interner = TyCtxt<'tcx>;
16
17    fn cx(&self) -> TyCtxt<'tcx> {
18        self.tcx
19    }
20
21    fn next_trait_solver(&self) -> bool {
22        self.next_trait_solver
23    }
24
25    fn typing_mode(&self) -> ty::TypingMode<'tcx> {
26        self.typing_mode()
27    }
28
29    fn universe(&self) -> ty::UniverseIndex {
30        self.universe()
31    }
32
33    fn create_next_universe(&self) -> ty::UniverseIndex {
34        self.create_next_universe()
35    }
36
37    fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> {
38        match self.probe_ty_var(vid) {
39            Err(universe) => Some(universe),
40            Ok(_) => None,
41        }
42    }
43
44    fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
45        match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
46            Err(universe) => Some(universe),
47            Ok(_) => None,
48        }
49    }
50
51    fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex> {
52        match self.probe_const_var(ct) {
53            Err(universe) => Some(universe),
54            Ok(_) => None,
55        }
56    }
57
58    fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid {
59        self.root_var(var)
60    }
61
62    fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
63        self.root_const_var(var)
64    }
65
66    fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> {
67        match self.probe_ty_var(vid) {
68            Ok(ty) => ty,
69            Err(_) => Ty::new_var(self.tcx, self.root_var(vid)),
70        }
71    }
72
73    fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
74        self.opportunistic_resolve_int_var(vid)
75    }
76
77    fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
78        self.opportunistic_resolve_float_var(vid)
79    }
80
81    fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> {
82        match self.probe_const_var(vid) {
83            Ok(ct) => ct,
84            Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)),
85        }
86    }
87
88    fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
89        self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
90    }
91
92    fn is_changed_arg(&self, arg: ty::GenericArg<'tcx>) -> bool {
93        match arg.kind() {
94            ty::GenericArgKind::Lifetime(_) => {
95                // Lifetimes should not change affect trait selection.
96                false
97            }
98            ty::GenericArgKind::Type(ty) => {
99                if let ty::Infer(infer_ty) = *ty.kind() {
100                    match infer_ty {
101                        ty::InferTy::TyVar(vid) => {
102                            !self.probe_ty_var(vid).is_err_and(|_| self.root_var(vid) == vid)
103                        }
104                        ty::InferTy::IntVar(vid) => {
105                            let mut inner = self.inner.borrow_mut();
106                            !matches!(
107                                inner.int_unification_table().probe_value(vid),
108                                ty::IntVarValue::Unknown
109                                    if inner.int_unification_table().find(vid) == vid
110                            )
111                        }
112                        ty::InferTy::FloatVar(vid) => {
113                            let mut inner = self.inner.borrow_mut();
114                            !matches!(
115                                inner.float_unification_table().probe_value(vid),
116                                ty::FloatVarValue::Unknown
117                                    if inner.float_unification_table().find(vid) == vid
118                            )
119                        }
120                        ty::InferTy::FreshTy(_)
121                        | ty::InferTy::FreshIntTy(_)
122                        | ty::InferTy::FreshFloatTy(_) => true,
123                    }
124                } else {
125                    true
126                }
127            }
128            ty::GenericArgKind::Const(ct) => {
129                if let ty::ConstKind::Infer(infer_ct) = ct.kind() {
130                    match infer_ct {
131                        ty::InferConst::Var(vid) => !self
132                            .probe_const_var(vid)
133                            .is_err_and(|_| self.root_const_var(vid) == vid),
134                        ty::InferConst::Fresh(_) => true,
135                    }
136                } else {
137                    true
138                }
139            }
140        }
141    }
142
143    fn next_region_infer(&self) -> ty::Region<'tcx> {
144        self.next_region_var(RegionVariableOrigin::Misc(DUMMY_SP))
145    }
146
147    fn next_ty_infer(&self) -> Ty<'tcx> {
148        self.next_ty_var(DUMMY_SP)
149    }
150
151    fn next_const_infer(&self) -> ty::Const<'tcx> {
152        self.next_const_var(DUMMY_SP)
153    }
154
155    fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
156        self.fresh_args_for_item(DUMMY_SP, def_id)
157    }
158
159    fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
160        &self,
161        value: ty::Binder<'tcx, T>,
162    ) -> T {
163        self.instantiate_binder_with_fresh_vars(
164            DUMMY_SP,
165            BoundRegionConversionTime::HigherRankedType,
166            value,
167        )
168    }
169
170    fn enter_forall<T: TypeFoldable<TyCtxt<'tcx>>, U>(
171        &self,
172        value: ty::Binder<'tcx, T>,
173        f: impl FnOnce(T) -> U,
174    ) -> U {
175        self.enter_forall(value, f)
176    }
177
178    fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
179        self.inner.borrow_mut().type_variables().equate(a, b);
180    }
181
182    fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) {
183        self.inner.borrow_mut().int_unification_table().union(a, b);
184    }
185
186    fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid) {
187        self.inner.borrow_mut().float_unification_table().union(a, b);
188    }
189
190    fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid) {
191        self.inner.borrow_mut().const_unification_table().union(a, b);
192    }
193
194    fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
195        &self,
196        relation: &mut R,
197        target_is_expected: bool,
198        target_vid: ty::TyVid,
199        instantiation_variance: ty::Variance,
200        source_ty: Ty<'tcx>,
201    ) -> RelateResult<'tcx, ()> {
202        self.instantiate_ty_var(
203            relation,
204            target_is_expected,
205            target_vid,
206            instantiation_variance,
207            source_ty,
208        )
209    }
210
211    fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue) {
212        self.inner.borrow_mut().int_unification_table().union_value(vid, value);
213    }
214
215    fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue) {
216        self.inner.borrow_mut().float_unification_table().union_value(vid, value);
217    }
218
219    fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
220        &self,
221        relation: &mut R,
222        target_is_expected: bool,
223        target_vid: ty::ConstVid,
224        source_ct: ty::Const<'tcx>,
225    ) -> RelateResult<'tcx, ()> {
226        self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
227    }
228
229    fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
230        self.set_tainted_by_errors(e)
231    }
232
233    fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
234        self.shallow_resolve(ty)
235    }
236    fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
237        self.shallow_resolve_const(ct)
238    }
239
240    fn resolve_vars_if_possible<T>(&self, value: T) -> T
241    where
242        T: TypeFoldable<TyCtxt<'tcx>>,
243    {
244        self.resolve_vars_if_possible(value)
245    }
246
247    fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
248        self.probe(|_| probe())
249    }
250
251    fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>, span: Span) {
252        self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
253            SubregionOrigin::RelateRegionParamBound(span, None),
254            sub,
255            sup,
256        );
257    }
258
259    fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>, span: Span) {
260        self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
261            SubregionOrigin::RelateRegionParamBound(span, None),
262            a,
263            b,
264        );
265    }
266
267    fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
268        self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy_with_span(span));
269    }
270
271    type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
272    fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
273        self.inner.borrow_mut().opaque_types().num_entries()
274    }
275    fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
276        self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
277    }
278    fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
279        self.inner
280            .borrow_mut()
281            .opaque_types()
282            .iter_duplicate_entries()
283            .map(|(k, h)| (k, h.ty))
284            .collect()
285    }
286    fn clone_opaque_types_added_since(
287        &self,
288        prev_entries: OpaqueTypeStorageEntries,
289    ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
290        self.inner
291            .borrow_mut()
292            .opaque_types()
293            .opaque_types_added_since(prev_entries)
294            .map(|(k, h)| (k, h.ty))
295            .collect()
296    }
297
298    fn register_hidden_type_in_storage(
299        &self,
300        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
301        hidden_ty: Ty<'tcx>,
302        span: Span,
303    ) -> Option<Ty<'tcx>> {
304        self.register_hidden_type_in_storage(
305            opaque_type_key,
306            ty::OpaqueHiddenType { span, ty: hidden_ty },
307        )
308    }
309    fn add_duplicate_opaque_type(
310        &self,
311        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
312        hidden_ty: Ty<'tcx>,
313        span: Span,
314    ) {
315        self.inner
316            .borrow_mut()
317            .opaque_types()
318            .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty })
319    }
320
321    fn reset_opaque_types(&self) {
322        let _ = self.take_opaque_types();
323    }
324}