Skip to main content

hir_ty/next_solver/infer/
context.rs

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