Skip to main content

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 disable_trait_solver_fast_paths(&self) -> bool {
26        self.disable_trait_solver_fast_paths()
27    }
28
29    fn typing_mode_raw(&self) -> ty::TypingMode<'tcx> {
30        self.typing_mode_raw()
31    }
32
33    fn universe(&self) -> ty::UniverseIndex {
34        self.universe()
35    }
36
37    fn create_next_universe(&self) -> ty::UniverseIndex {
38        self.create_next_universe()
39    }
40
41    fn insert_placeholder_assumptions(
42        &self,
43        u: ty::UniverseIndex,
44        assumptions: Option<rustc_type_ir::region_constraint::Assumptions<TyCtxt<'tcx>>>,
45    ) {
46        self.placeholder_assumptions_for_next_solver.borrow_mut().insert(u, assumptions);
47    }
48
49    fn get_placeholder_assumptions(
50        &self,
51        u: ty::UniverseIndex,
52    ) -> Option<rustc_type_ir::region_constraint::Assumptions<TyCtxt<'tcx>>> {
53        self.placeholder_assumptions_for_next_solver.borrow().get(&u).unwrap().as_ref().cloned()
54    }
55
56    fn get_solver_region_constraint(
57        &self,
58    ) -> rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>> {
59        self.inner.borrow().solver_region_constraint_storage.get_constraint()
60    }
61
62    fn overwrite_solver_region_constraint(
63        &self,
64        constraint: rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>>,
65    ) {
66        let mut inner = self.inner.borrow_mut();
67        use rustc_data_structures::undo_log::UndoLogs;
68
69        use crate::infer::UndoLog;
70        let old_constraint = inner.solver_region_constraint_storage.get_constraint();
71        inner.undo_log.push(UndoLog::OverwriteSolverRegionConstraint { old_constraint });
72        inner.solver_region_constraint_storage.overwrite_solver_region_constraint(constraint);
73    }
74
75    fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> {
76        match self.try_resolve_ty_var(vid) {
77            Err(universe) => Some(universe),
78            Ok(_) => None,
79        }
80    }
81
82    fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
83        match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
84            Err(universe) => Some(universe),
85            Ok(_) => None,
86        }
87    }
88
89    fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex> {
90        match self.try_resolve_const_var(ct) {
91            Err(universe) => Some(universe),
92            Ok(_) => None,
93        }
94    }
95
96    fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid {
97        self.root_var(var)
98    }
99
100    fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid {
101        self.sub_unification_table_root_var(var)
102    }
103
104    fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
105        self.root_const_var(var)
106    }
107
108    fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> {
109        match self.try_resolve_ty_var(vid) {
110            Ok(ty) => ty,
111            Err(_) => Ty::new_var(self.tcx, self.root_var(vid)),
112        }
113    }
114
115    fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
116        self.opportunistic_resolve_int_var(vid)
117    }
118
119    fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
120        self.opportunistic_resolve_float_var(vid)
121    }
122
123    fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> {
124        match self.try_resolve_const_var(vid) {
125            Ok(ct) => ct,
126            Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)),
127        }
128    }
129
130    fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
131        self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
132    }
133
134    fn is_changed_arg(&self, arg: ty::GenericArg<'tcx>) -> bool {
135        match arg.kind() {
136            ty::GenericArgKind::Lifetime(_) => {
137                // Lifetimes should not change affect trait selection.
138                false
139            }
140            ty::GenericArgKind::Type(ty) => {
141                if let ty::Infer(infer_ty) = *ty.kind() {
142                    match infer_ty {
143                        ty::InferTy::TyVar(vid) => {
144                            !self.try_resolve_ty_var(vid).is_err_and(|_| self.root_var(vid) == vid)
145                        }
146                        ty::InferTy::IntVar(vid) => {
147                            let mut inner = self.inner.borrow_mut();
148                            !#[allow(non_exhaustive_omitted_patterns)] match inner.int_unification_table().probe_value(vid)
    {
    ty::IntVarValue::Unknown if inner.int_unification_table().find(vid) == vid
        => true,
    _ => false,
}matches!(
149                                inner.int_unification_table().probe_value(vid),
150                                ty::IntVarValue::Unknown
151                                    if inner.int_unification_table().find(vid) == vid
152                            )
153                        }
154                        ty::InferTy::FloatVar(vid) => {
155                            let mut inner = self.inner.borrow_mut();
156                            !#[allow(non_exhaustive_omitted_patterns)] match inner.float_unification_table().probe_value(vid)
    {
    ty::FloatVarValue::Unknown if
        inner.float_unification_table().find(vid) == vid => true,
    _ => false,
}matches!(
157                                inner.float_unification_table().probe_value(vid),
158                                ty::FloatVarValue::Unknown
159                                    if inner.float_unification_table().find(vid) == vid
160                            )
161                        }
162                        ty::InferTy::FreshTy(_)
163                        | ty::InferTy::FreshIntTy(_)
164                        | ty::InferTy::FreshFloatTy(_) => true,
165                    }
166                } else {
167                    true
168                }
169            }
170            ty::GenericArgKind::Const(ct) => {
171                if let ty::ConstKind::Infer(infer_ct) = ct.kind() {
172                    match infer_ct {
173                        ty::InferConst::Var(vid) => !self
174                            .try_resolve_const_var(vid)
175                            .is_err_and(|_| self.root_const_var(vid) == vid),
176                        ty::InferConst::Fresh(_) => true,
177                    }
178                } else {
179                    true
180                }
181            }
182        }
183    }
184
185    fn next_region_infer(&self) -> ty::Region<'tcx> {
186        self.next_region_var(RegionVariableOrigin::Misc(DUMMY_SP))
187    }
188
189    fn next_ty_infer(&self) -> Ty<'tcx> {
190        self.next_ty_var(DUMMY_SP)
191    }
192
193    fn next_const_infer(&self) -> ty::Const<'tcx> {
194        self.next_const_var(DUMMY_SP)
195    }
196
197    fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
198        self.fresh_args_for_item(DUMMY_SP, def_id)
199    }
200
201    fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
202        &self,
203        value: ty::Binder<'tcx, T>,
204    ) -> T {
205        self.instantiate_binder_with_fresh_vars(
206            DUMMY_SP,
207            BoundRegionConversionTime::HigherRankedType,
208            value,
209        )
210    }
211
212    fn enter_forall_without_assumptions<T: TypeFoldable<TyCtxt<'tcx>>, U>(
213        &self,
214        value: ty::Binder<'tcx, T>,
215        f: impl FnOnce(T) -> U,
216    ) -> U {
217        self.enter_forall(value, f)
218    }
219
220    fn enter_forall_with_empty_assumptions<T: TypeFoldable<TyCtxt<'tcx>>, U>(
221        &self,
222        value: ty::Binder<'tcx, T>,
223        f: impl FnOnce(T) -> U,
224    ) -> U {
225        self.enter_forall(value, |value| {
226            let u = self.universe();
227            self.placeholder_assumptions_for_next_solver
228                .borrow_mut()
229                .insert(u, Some(rustc_type_ir::region_constraint::Assumptions::empty()));
230            f(value)
231        })
232    }
233
234    fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
235        self.inner.borrow_mut().type_variables().equate(a, b);
236    }
237
238    fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
239        self.sub_unify_ty_vids_raw(a, b);
240    }
241
242    fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) {
243        self.inner.borrow_mut().int_unification_table().union(a, b);
244    }
245
246    fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid) {
247        self.inner.borrow_mut().float_unification_table().union(a, b);
248    }
249
250    fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid) {
251        self.inner.borrow_mut().const_unification_table().union(a, b);
252    }
253
254    fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
255        &self,
256        relation: &mut R,
257        target_is_expected: bool,
258        target_vid: ty::TyVid,
259        instantiation_variance: ty::Variance,
260        source_ty: Ty<'tcx>,
261    ) -> RelateResult<'tcx, ()> {
262        self.instantiate_ty_var(
263            relation,
264            target_is_expected,
265            target_vid,
266            instantiation_variance,
267            source_ty,
268        )
269    }
270
271    fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue) {
272        self.inner.borrow_mut().int_unification_table().union_value(vid, value);
273    }
274
275    fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue) {
276        self.inner.borrow_mut().float_unification_table().union_value(vid, value);
277    }
278
279    fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
280        &self,
281        relation: &mut R,
282        target_is_expected: bool,
283        target_vid: ty::ConstVid,
284        source_ct: ty::Const<'tcx>,
285    ) -> RelateResult<'tcx, ()> {
286        self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
287    }
288
289    fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
290        self.set_tainted_by_errors(e)
291    }
292
293    fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
294        self.shallow_resolve(ty)
295    }
296    fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
297        self.shallow_resolve_const(ct)
298    }
299
300    fn resolve_vars_if_possible<T>(&self, value: T) -> T
301    where
302        T: TypeFoldable<TyCtxt<'tcx>>,
303    {
304        self.resolve_vars_if_possible(value)
305    }
306
307    fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
308        self.probe(|_| probe())
309    }
310
311    fn sub_regions(
312        &self,
313        sub: ty::Region<'tcx>,
314        sup: ty::Region<'tcx>,
315        vis: ty::VisibleForLeakCheck,
316        span: Span,
317    ) {
318        self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
319            SubregionOrigin::RelateRegionParamBound(span, None),
320            sub,
321            sup,
322            vis,
323        );
324    }
325
326    fn equate_regions(
327        &self,
328        a: ty::Region<'tcx>,
329        b: ty::Region<'tcx>,
330        vis: ty::VisibleForLeakCheck,
331        span: Span,
332    ) {
333        self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
334            SubregionOrigin::RelateRegionParamBound(span, None),
335            a,
336            b,
337            vis,
338        );
339    }
340
341    fn register_solver_region_constraint(
342        &self,
343        c: rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>>,
344    ) {
345        let mut inner = self.inner.borrow_mut();
346        use rustc_data_structures::undo_log::UndoLogs;
347
348        use crate::infer::UndoLog;
349        inner.undo_log.push(UndoLog::PushSolverRegionConstraint);
350        inner.solver_region_constraint_storage.push(c);
351    }
352
353    fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
354        self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy_with_span(span));
355    }
356
357    type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
358    fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
359        self.inner.borrow_mut().opaque_types().num_entries()
360    }
361    fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
362        self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
363    }
364    fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
365        self.inner
366            .borrow_mut()
367            .opaque_types()
368            .iter_duplicate_entries()
369            .map(|(k, h)| (k, h.ty))
370            .collect()
371    }
372    fn clone_opaque_types_added_since(
373        &self,
374        prev_entries: OpaqueTypeStorageEntries,
375    ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
376        self.inner
377            .borrow_mut()
378            .opaque_types()
379            .opaque_types_added_since(prev_entries)
380            .map(|(k, h)| (k, h.ty))
381            .collect()
382    }
383    fn opaques_with_sub_unified_hidden_type(&self, ty: ty::TyVid) -> Vec<ty::AliasTy<'tcx>> {
384        self.opaques_with_sub_unified_hidden_type(ty)
385    }
386
387    fn register_hidden_type_in_storage(
388        &self,
389        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
390        hidden_ty: Ty<'tcx>,
391        span: Span,
392    ) -> Option<Ty<'tcx>> {
393        self.register_hidden_type_in_storage(
394            opaque_type_key,
395            ty::ProvisionalHiddenType { span, ty: hidden_ty },
396        )
397    }
398    fn add_duplicate_opaque_type(
399        &self,
400        opaque_type_key: ty::OpaqueTypeKey<'tcx>,
401        hidden_ty: Ty<'tcx>,
402        span: Span,
403    ) {
404        self.inner
405            .borrow_mut()
406            .opaque_types()
407            .add_duplicate(opaque_type_key, ty::ProvisionalHiddenType { span, ty: hidden_ty })
408    }
409
410    fn reset_opaque_types(&self) {
411        let _ = self.take_opaque_types();
412    }
413}