1use 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 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<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 equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
221 self.inner.borrow_mut().type_variables().equate(a, b);
222 }
223
224 fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
225 self.sub_unify_ty_vids_raw(a, b);
226 }
227
228 fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) {
229 self.inner.borrow_mut().int_unification_table().union(a, b);
230 }
231
232 fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid) {
233 self.inner.borrow_mut().float_unification_table().union(a, b);
234 }
235
236 fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid) {
237 self.inner.borrow_mut().const_unification_table().union(a, b);
238 }
239
240 fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
241 &self,
242 relation: &mut R,
243 target_is_expected: bool,
244 target_vid: ty::TyVid,
245 instantiation_variance: ty::Variance,
246 source_ty: Ty<'tcx>,
247 ) -> RelateResult<'tcx, ()> {
248 self.instantiate_ty_var(
249 relation,
250 target_is_expected,
251 target_vid,
252 instantiation_variance,
253 source_ty,
254 )
255 }
256
257 fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue) {
258 self.inner.borrow_mut().int_unification_table().union_value(vid, value);
259 }
260
261 fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue) {
262 self.inner.borrow_mut().float_unification_table().union_value(vid, value);
263 }
264
265 fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
266 &self,
267 relation: &mut R,
268 target_is_expected: bool,
269 target_vid: ty::ConstVid,
270 source_ct: ty::Const<'tcx>,
271 ) -> RelateResult<'tcx, ()> {
272 self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
273 }
274
275 fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
276 self.set_tainted_by_errors(e)
277 }
278
279 fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
280 self.shallow_resolve(ty)
281 }
282 fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
283 self.shallow_resolve_const(ct)
284 }
285
286 fn resolve_vars_if_possible<T>(&self, value: T) -> T
287 where
288 T: TypeFoldable<TyCtxt<'tcx>>,
289 {
290 self.resolve_vars_if_possible(value)
291 }
292
293 fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
294 self.probe(|_| probe())
295 }
296
297 fn sub_regions(
298 &self,
299 sub: ty::Region<'tcx>,
300 sup: ty::Region<'tcx>,
301 vis: ty::VisibleForLeakCheck,
302 span: Span,
303 ) {
304 self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
305 SubregionOrigin::RelateRegionParamBound(span, None),
306 sub,
307 sup,
308 vis,
309 );
310 }
311
312 fn equate_regions(
313 &self,
314 a: ty::Region<'tcx>,
315 b: ty::Region<'tcx>,
316 vis: ty::VisibleForLeakCheck,
317 span: Span,
318 ) {
319 self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
320 SubregionOrigin::RelateRegionParamBound(span, None),
321 a,
322 b,
323 vis,
324 );
325 }
326
327 fn register_solver_region_constraint(
328 &self,
329 c: rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>>,
330 ) {
331 let mut inner = self.inner.borrow_mut();
332 use rustc_data_structures::undo_log::UndoLogs;
333
334 use crate::infer::UndoLog;
335 inner.undo_log.push(UndoLog::PushSolverRegionConstraint);
336 inner.solver_region_constraint_storage.push(c);
337 }
338
339 fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
340 self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy_with_span(span));
341 }
342
343 type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
344 fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
345 self.inner.borrow_mut().opaque_types().num_entries()
346 }
347 fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
348 self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
349 }
350 fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
351 self.inner
352 .borrow_mut()
353 .opaque_types()
354 .iter_duplicate_entries()
355 .map(|(k, h)| (k, h.ty))
356 .collect()
357 }
358 fn clone_opaque_types_added_since(
359 &self,
360 prev_entries: OpaqueTypeStorageEntries,
361 ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
362 self.inner
363 .borrow_mut()
364 .opaque_types()
365 .opaque_types_added_since(prev_entries)
366 .map(|(k, h)| (k, h.ty))
367 .collect()
368 }
369 fn opaques_with_sub_unified_hidden_type(&self, ty: ty::TyVid) -> Vec<ty::AliasTy<'tcx>> {
370 self.opaques_with_sub_unified_hidden_type(ty)
371 }
372
373 fn register_hidden_type_in_storage(
374 &self,
375 opaque_type_key: ty::OpaqueTypeKey<'tcx>,
376 hidden_ty: Ty<'tcx>,
377 span: Span,
378 ) -> Option<Ty<'tcx>> {
379 self.register_hidden_type_in_storage(
380 opaque_type_key,
381 ty::ProvisionalHiddenType { span, ty: hidden_ty },
382 )
383 }
384 fn add_duplicate_opaque_type(
385 &self,
386 opaque_type_key: ty::OpaqueTypeKey<'tcx>,
387 hidden_ty: Ty<'tcx>,
388 span: Span,
389 ) {
390 self.inner
391 .borrow_mut()
392 .opaque_types()
393 .add_duplicate(opaque_type_key, ty::ProvisionalHiddenType { span, ty: hidden_ty })
394 }
395
396 fn reset_opaque_types(&self) {
397 let _ = self.take_opaque_types();
398 }
399}