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