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