1use rustc_data_structures::sso::SsoHashMap;
3use rustc_hir::def_id::DefId;
4use rustc_middle::traits::ObligationCause;
5use rustc_middle::ty::relate::RelateResult;
6use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
7use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
8use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
9use rustc_type_ir::solve::TyOrConstInferVar;
10use rustc_type_ir::{TypeSuperFoldable, TypeVisitableExt};
11
12use super::type_variable::TypeVariableValue;
13use super::{
14 BoundRegionConversionTime, ConstVariableValue, InferCtxt, OpaqueTypeStorageEntries,
15 RegionVariableOrigin, SubregionOrigin,
16};
17
18impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
19 type Interner = TyCtxt<'tcx>;
20
21 fn cx(&self) -> TyCtxt<'tcx> {
22 self.tcx
23 }
24
25 fn next_trait_solver(&self) -> bool {
26 self.next_trait_solver
27 }
28
29 fn enable_next_solver_overflow_fcw(&self) -> bool {
30 self.enable_next_solver_overflow_fcw.get()
31 }
32
33 fn disable_trait_solver_fast_paths(&self) -> bool {
34 self.disable_trait_solver_fast_paths()
35 }
36
37 fn typing_mode_raw(&self) -> ty::TypingMode<'tcx> {
38 self.typing_mode_raw()
39 }
40
41 fn universe(&self) -> ty::UniverseIndex {
42 self.universe()
43 }
44
45 fn create_next_universe(&self) -> ty::UniverseIndex {
46 self.create_next_universe()
47 }
48
49 fn insert_placeholder_assumptions(
50 &self,
51 u: ty::UniverseIndex,
52 assumptions: Option<rustc_type_ir::region_constraint::Assumptions<TyCtxt<'tcx>>>,
53 ) {
54 self.insert_placeholder_assumptions(u, assumptions);
55 }
56
57 fn get_placeholder_assumptions(
58 &self,
59 u: ty::UniverseIndex,
60 ) -> Option<rustc_type_ir::region_constraint::Assumptions<TyCtxt<'tcx>>> {
61 self.get_placeholder_assumptions(u)
62 }
63
64 fn get_solver_region_constraint(
65 &self,
66 ) -> rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>> {
67 self.get_solver_region_constraint().without_spans()
68 }
69
70 fn overwrite_solver_region_constraint(
71 &self,
72 constraint: rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>>,
73 span: Span,
74 ) {
75 self.overwrite_solver_region_constraint(constraint.with_span(span));
76 }
77
78 fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> {
79 match self.try_resolve_ty_var(vid) {
80 Err(universe) => Some(universe),
81 Ok(_) => None,
82 }
83 }
84
85 fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
86 match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
87 Err(universe) => Some(universe),
88 Ok(_) => None,
89 }
90 }
91
92 fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex> {
93 match self.try_resolve_const_var(ct) {
94 Err(universe) => Some(universe),
95 Ok(_) => None,
96 }
97 }
98
99 fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid {
100 self.root_var(var)
101 }
102
103 fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid {
104 self.sub_unification_table_root_var(var)
105 }
106
107 #[inline]
108 fn is_sub_unification_table_root_var(&self, vid: ty::TyVid) -> bool {
109 self.inner
110 .borrow()
111 .type_variable_storage
112 .sub_unification_table_ref()
113 .try_probe_value(vid)
114 .is_some()
115 }
116
117 fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
118 self.root_const_var(var)
119 }
120
121 fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> {
122 match self.try_resolve_ty_var(vid) {
123 Ok(ty) => ty,
124 Err(_) => Ty::new_var(self.tcx, self.root_var(vid)),
125 }
126 }
127
128 fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
129 self.opportunistic_resolve_int_var(vid)
130 }
131
132 fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
133 self.opportunistic_resolve_float_var(vid)
134 }
135
136 fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> {
137 match self.try_resolve_const_var(vid) {
138 Ok(ct) => ct,
139 Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)),
140 }
141 }
142
143 fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
144 self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
145 }
146
147 fn ty_or_const_infer_var_changed(&self, var: TyOrConstInferVar) -> bool {
148 self.ty_or_const_infer_var_changed(var)
149 }
150
151 fn next_region_infer(&self) -> ty::Region<'tcx> {
152 self.next_region_var(RegionVariableOrigin::Misc(DUMMY_SP))
153 }
154
155 fn next_ty_infer(&self) -> Ty<'tcx> {
156 self.next_ty_var(DUMMY_SP)
157 }
158
159 fn next_const_infer(&self) -> ty::Const<'tcx> {
160 self.next_const_var(DUMMY_SP)
161 }
162
163 fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
164 self.fresh_args_for_item(DUMMY_SP, def_id)
165 }
166
167 fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
168 &self,
169 value: ty::Binder<'tcx, T>,
170 ) -> T {
171 self.instantiate_binder_with_fresh_vars(
172 DUMMY_SP,
173 BoundRegionConversionTime::HigherRankedType,
174 value,
175 )
176 }
177
178 fn enter_forall_without_assumptions<T: TypeFoldable<TyCtxt<'tcx>>, U>(
179 &self,
180 value: ty::Binder<'tcx, T>,
181 f: impl FnOnce(T) -> U,
182 ) -> U {
183 self.enter_forall(value, f)
184 }
185
186 fn enter_forall_with_empty_assumptions<T: TypeFoldable<TyCtxt<'tcx>>, U>(
187 &self,
188 value: ty::Binder<'tcx, T>,
189 f: impl FnOnce(T) -> U,
190 ) -> U {
191 self.enter_forall(value, |value| {
192 let u = self.universe();
193 self.placeholder_assumptions_for_next_solver
194 .borrow_mut()
195 .insert(u, Some(rustc_type_ir::region_constraint::Assumptions::empty()));
196 f(value)
197 })
198 }
199
200 fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
201 self.inner.borrow_mut().type_variables().equate(a, b);
202 }
203
204 fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
205 self.sub_unify_ty_vids_raw(a, b);
206 }
207
208 fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) {
209 self.inner.borrow_mut().int_unification_table().union(a, b);
210 }
211
212 fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid) {
213 self.inner.borrow_mut().float_unification_table().union(a, b);
214 }
215
216 fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid) {
217 self.inner.borrow_mut().const_unification_table().union(a, b);
218 }
219
220 fn instantiate_ty_var_raw(&self, vid: ty::TyVid, ty: Ty<'tcx>) {
221 let ty = lower_universe(self, self.try_resolve_ty_var(vid).unwrap_err(), ty);
222
223 self.inner.borrow_mut().type_variables().instantiate(vid, ty);
224 }
225
226 fn instantiate_const_var_raw(&self, vid: ty::ConstVid, ct: ty::Const<'tcx>) {
227 let ct = lower_universe(self, self.try_resolve_const_var(vid).unwrap_err(), ct);
228
229 self.inner
230 .borrow_mut()
231 .const_unification_table()
232 .union_value(vid, ConstVariableValue::Known { value: ct });
233 }
234
235 fn instantiate_ty_var<R: PredicateEmittingRelation<Self>>(
236 &self,
237 relation: &mut R,
238 target_is_expected: bool,
239 target_vid: ty::TyVid,
240 instantiation_variance: ty::Variance,
241 source_ty: Ty<'tcx>,
242 ) -> RelateResult<'tcx, ()> {
243 self.instantiate_ty_var(
244 relation,
245 target_is_expected,
246 target_vid,
247 instantiation_variance,
248 source_ty,
249 )
250 }
251
252 fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue) {
253 self.inner.borrow_mut().int_unification_table().union_value(vid, value);
254 }
255
256 fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue) {
257 self.inner.borrow_mut().float_unification_table().union_value(vid, value);
258 }
259
260 fn instantiate_const_var<R: PredicateEmittingRelation<Self>>(
261 &self,
262 relation: &mut R,
263 target_is_expected: bool,
264 target_vid: ty::ConstVid,
265 source_ct: ty::Const<'tcx>,
266 ) -> RelateResult<'tcx, ()> {
267 self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
268 }
269
270 fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
271 self.set_tainted_by_errors(e)
272 }
273
274 fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
275 self.shallow_resolve(ty)
276 }
277 fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
278 self.shallow_resolve_const(ct)
279 }
280
281 fn resolve_vars_if_possible<T>(&self, value: T) -> T
282 where
283 T: TypeFoldable<TyCtxt<'tcx>>,
284 {
285 self.resolve_vars_if_possible(value)
286 }
287
288 fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
289 self.probe(|_| probe())
290 }
291
292 fn commit_if_ok<T, E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<T, E> {
293 self.commit_if_ok(|_| f())
294 }
295
296 fn sub_regions(
297 &self,
298 sub: ty::Region<'tcx>,
299 sup: ty::Region<'tcx>,
300 vis: ty::VisibleForLeakCheck,
301 span: Span,
302 ) {
303 self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
304 SubregionOrigin::RelateRegionParamBound(span, None),
305 sub,
306 sup,
307 vis,
308 );
309 }
310
311 fn equate_regions(
312 &self,
313 a: ty::Region<'tcx>,
314 b: ty::Region<'tcx>,
315 vis: ty::VisibleForLeakCheck,
316 span: Span,
317 ) {
318 self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
319 SubregionOrigin::RelateRegionParamBound(span, None),
320 a,
321 b,
322 vis,
323 );
324 }
325
326 fn register_solver_region_constraint(
327 &self,
328 c: rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>>,
329 span: Span,
330 ) {
331 self.register_solver_region_constraint(c.with_span(span));
332 }
333
334 fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
335 self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy_with_span(span));
336 }
337
338 type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
339 #[inline]
340 fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
341 self.inner.borrow_mut().opaque_types().num_entries()
342 }
343 fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
344 self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
345 }
346 fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
347 self.inner
348 .borrow_mut()
349 .opaque_types()
350 .iter_duplicate_entries()
351 .map(|(k, h)| (k, h.ty))
352 .collect()
353 }
354 fn clone_opaque_types_added_since(
355 &self,
356 prev_entries: OpaqueTypeStorageEntries,
357 ) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
358 self.inner
359 .borrow_mut()
360 .opaque_types()
361 .opaque_types_added_since(prev_entries)
362 .map(|(k, h)| (k, h.ty))
363 .collect()
364 }
365 fn opaques_with_sub_unified_hidden_type(&self, ty: ty::TyVid) -> Vec<ty::OpaqueAliasTy<'tcx>> {
366 self.opaques_with_sub_unified_hidden_type(ty)
367 }
368
369 fn register_hidden_type_in_storage(
370 &self,
371 opaque_type_key: ty::OpaqueTypeKey<'tcx>,
372 hidden_ty: Ty<'tcx>,
373 span: Span,
374 ) -> Option<Ty<'tcx>> {
375 self.register_hidden_type_in_storage(
376 opaque_type_key,
377 ty::ProvisionalHiddenType { span, ty: hidden_ty },
378 )
379 }
380 fn add_duplicate_opaque_type(
381 &self,
382 opaque_type_key: ty::OpaqueTypeKey<'tcx>,
383 hidden_ty: Ty<'tcx>,
384 span: Span,
385 ) {
386 self.inner
387 .borrow_mut()
388 .opaque_types()
389 .add_duplicate(opaque_type_key, ty::ProvisionalHiddenType { span, ty: hidden_ty })
390 }
391
392 fn reset_opaque_types(&self) {
393 let _ = self.take_opaque_types();
394 }
395}
396
397fn lower_universe<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
398 infcx: &InferCtxt<'tcx>,
399 for_universe: ty::UniverseIndex,
400 value: T,
401) -> T {
402 let value = value.fold_with(&mut LowerUniverseFolder {
403 infcx,
404 for_universe,
405 cache: Default::default(),
406 });
407
408 #[cfg(debug_assertions)]
411 {
412 let value_universe = ty::max_universe(infcx, value);
413 if !for_universe.can_name(value_universe) {
{
::core::panicking::panic_fmt(format_args!("variable in universe {0:?} can\'t name value in universe {1:?}",
for_universe, value_universe));
}
};assert!(
414 for_universe.can_name(value_universe),
415 "variable in universe {:?} can't name value in universe {:?}",
416 for_universe,
417 value_universe,
418 );
419 }
420
421 value
422}
423
424struct LowerUniverseFolder<'a, 'tcx> {
435 infcx: &'a InferCtxt<'tcx>,
436 for_universe: ty::UniverseIndex,
437 cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
438}
439impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for LowerUniverseFolder<'a, 'tcx> {
440 fn cx(&self) -> TyCtxt<'tcx> {
441 self.infcx.tcx
442 }
443
444 fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
445 if !(t.has_free_regions() || t.has_infer()) {
446 return t;
447 }
448
449 if let Some(&answer) = self.cache.get(&t) {
450 return answer;
451 }
452
453 let folded = match t.kind() {
454 ty::Infer(ty::TyVar(vid)) => {
455 let vid = self.infcx.root_var(*vid);
456 let probe = self.infcx.inner.borrow_mut().type_variables().probe(vid);
457 match probe {
458 TypeVariableValue::Known { value: u } => u.super_fold_with(self),
459 TypeVariableValue::Unknown { universe } => {
460 if self.for_universe.can_name(universe) {
461 t
462 } else {
463 let mut inner = self.infcx.inner.borrow_mut();
464 let origin = inner.type_variables().var_origin(vid);
465 let new_var_id =
466 inner.type_variables().new_var(self.for_universe, origin);
467 inner.type_variables().equate(vid, new_var_id);
468 Ty::new_var(self.cx(), new_var_id)
469 }
470 }
471 }
472 }
473 _ => t.super_fold_with(self),
474 };
475
476 self.cache.insert(t, folded);
477 folded
478 }
479
480 fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
481 if !(c.has_free_regions() || c.has_infer()) {
482 return c;
483 }
484
485 match c.kind() {
486 ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
487 let vid = self.infcx.root_const_var(vid);
488 let universe = match self.infcx.try_resolve_const_var(vid) {
489 Ok(value) => return value.fold_with(self),
490 Err(universe) => universe,
491 };
492 if self.for_universe.can_name(universe) {
493 c
494 } else {
495 let origin = self.infcx.const_var_origin(vid).unwrap();
496 let new_var_id = self
497 .infcx
498 .inner
499 .borrow_mut()
500 .const_unification_table()
501 .new_key(ConstVariableValue::Unknown {
502 origin,
503 universe: self.for_universe,
504 })
505 .vid;
506
507 self.infcx.inner.borrow_mut().const_unification_table().union(vid, new_var_id);
508
509 ty::Const::new_var(self.cx(), new_var_id)
510 }
511 }
512 _ => c.super_fold_with(self),
513 }
514 }
515
516 fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
517 match r.kind() {
518 ty::ReBound(..) | ty::ReErased => r,
519 _ => {
520 let r_universe = self.infcx.universe_of_region(r);
521 if self.for_universe.can_name(r_universe) {
522 r
523 } else {
524 let new_region = self.infcx.next_region_var_in_universe(
527 RegionVariableOrigin::Misc(DUMMY_SP),
528 self.for_universe,
529 );
530 self.infcx.equate_regions(
531 SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
532 r,
533 new_region,
534 ty::VisibleForLeakCheck::Yes,
535 );
536 new_region
537 }
538 }
539 }
540 }
541}