1#![allow(rustc::diagnostic_outside_of_impl)]
16#![allow(rustc::untranslatable_diagnostic)]
17
18use std::cell::Cell;
19use std::iter;
20
21use rustc_data_structures::fx::FxIndexMap;
22use rustc_errors::Diag;
23use rustc_hir::BodyOwnerKind;
24use rustc_hir::def::DefKind;
25use rustc_hir::def_id::{DefId, LocalDefId};
26use rustc_hir::lang_items::LangItem;
27use rustc_index::IndexVec;
28use rustc_infer::infer::NllRegionVariableOrigin;
29use rustc_macros::extension;
30use rustc_middle::ty::print::with_no_trimmed_paths;
31use rustc_middle::ty::{
32 self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty,
33 TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions,
34};
35use rustc_middle::{bug, span_bug};
36use rustc_span::{ErrorGuaranteed, kw, sym};
37use tracing::{debug, instrument};
38
39use crate::BorrowckInferCtxt;
40use crate::renumber::RegionCtxt;
41
42#[derive(Debug)]
43#[derive(Clone)] pub(crate) struct UniversalRegions<'tcx> {
45 indices: UniversalRegionIndices<'tcx>,
46
47 pub fr_static: RegionVid,
49
50 pub fr_fn_body: RegionVid,
54
55 first_extern_index: usize,
62
63 first_local_index: usize,
65
66 num_universals: usize,
68
69 pub defining_ty: DefiningTy<'tcx>,
73
74 pub unnormalized_output_ty: Ty<'tcx>,
80
81 pub unnormalized_input_tys: &'tcx [Ty<'tcx>],
87
88 pub yield_ty: Option<Ty<'tcx>>,
89
90 pub resume_ty: Option<Ty<'tcx>>,
91}
92
93#[derive(Copy, Clone, Debug)]
100pub(crate) enum DefiningTy<'tcx> {
101 Closure(DefId, GenericArgsRef<'tcx>),
104
105 Coroutine(DefId, GenericArgsRef<'tcx>),
109
110 CoroutineClosure(DefId, GenericArgsRef<'tcx>),
116
117 FnDef(DefId, GenericArgsRef<'tcx>),
120
121 Const(DefId, GenericArgsRef<'tcx>),
125
126 InlineConst(DefId, GenericArgsRef<'tcx>),
129
130 GlobalAsm(DefId),
134}
135
136impl<'tcx> DefiningTy<'tcx> {
137 pub(crate) fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
142 match self {
143 DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
144 DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(),
145 DefiningTy::Coroutine(_, args) => args.as_coroutine().upvar_tys(),
146 DefiningTy::FnDef(..)
147 | DefiningTy::Const(..)
148 | DefiningTy::InlineConst(..)
149 | DefiningTy::GlobalAsm(_) => ty::List::empty(),
150 }
151 }
152
153 pub(crate) fn implicit_inputs(self) -> usize {
157 match self {
158 DefiningTy::Closure(..)
159 | DefiningTy::CoroutineClosure(..)
160 | DefiningTy::Coroutine(..) => 1,
161 DefiningTy::FnDef(..)
162 | DefiningTy::Const(..)
163 | DefiningTy::InlineConst(..)
164 | DefiningTy::GlobalAsm(_) => 0,
165 }
166 }
167
168 pub(crate) fn is_fn_def(&self) -> bool {
169 matches!(*self, DefiningTy::FnDef(..))
170 }
171
172 pub(crate) fn is_const(&self) -> bool {
173 matches!(*self, DefiningTy::Const(..) | DefiningTy::InlineConst(..))
174 }
175
176 pub(crate) fn def_id(&self) -> DefId {
177 match *self {
178 DefiningTy::Closure(def_id, ..)
179 | DefiningTy::CoroutineClosure(def_id, ..)
180 | DefiningTy::Coroutine(def_id, ..)
181 | DefiningTy::FnDef(def_id, ..)
182 | DefiningTy::Const(def_id, ..)
183 | DefiningTy::InlineConst(def_id, ..)
184 | DefiningTy::GlobalAsm(def_id) => def_id,
185 }
186 }
187
188 pub(crate) fn args(&self) -> ty::GenericArgsRef<'tcx> {
191 match *self {
192 DefiningTy::Closure(_, args)
193 | DefiningTy::Coroutine(_, args)
194 | DefiningTy::CoroutineClosure(_, args)
195 | DefiningTy::FnDef(_, args)
196 | DefiningTy::Const(_, args)
197 | DefiningTy::InlineConst(_, args) => args,
198 DefiningTy::GlobalAsm(_) => ty::List::empty(),
199 }
200 }
201}
202
203#[derive(Debug)]
204#[derive(Clone)] struct UniversalRegionIndices<'tcx> {
206 indices: FxIndexMap<ty::Region<'tcx>, RegionVid>,
216
217 pub fr_static: RegionVid,
219
220 pub encountered_re_error: Cell<Option<ErrorGuaranteed>>,
223}
224
225#[derive(Debug, PartialEq)]
226pub(crate) enum RegionClassification {
227 Global,
230
231 External,
253
254 Local,
266}
267
268const FIRST_GLOBAL_INDEX: usize = 0;
269
270impl<'tcx> UniversalRegions<'tcx> {
271 pub(crate) fn new(infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId) -> Self {
277 UniversalRegionsBuilder { infcx, mir_def }.build()
278 }
279
280 pub(crate) fn closure_mapping(
290 tcx: TyCtxt<'tcx>,
291 closure_args: GenericArgsRef<'tcx>,
292 expected_num_vars: usize,
293 closure_def_id: LocalDefId,
294 ) -> IndexVec<RegionVid, ty::Region<'tcx>> {
295 let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
296 region_mapping.push(tcx.lifetimes.re_static);
297 tcx.for_each_free_region(&closure_args, |fr| {
298 region_mapping.push(fr);
299 });
300
301 for_each_late_bound_region_in_recursive_scope(tcx, tcx.local_parent(closure_def_id), |r| {
302 region_mapping.push(r);
303 });
304
305 assert_eq!(
306 region_mapping.len(),
307 expected_num_vars,
308 "index vec had unexpected number of variables"
309 );
310
311 region_mapping
312 }
313
314 pub(crate) fn is_universal_region(&self, r: RegionVid) -> bool {
316 (FIRST_GLOBAL_INDEX..self.num_universals).contains(&r.index())
317 }
318
319 pub(crate) fn region_classification(&self, r: RegionVid) -> Option<RegionClassification> {
322 let index = r.index();
323 if (FIRST_GLOBAL_INDEX..self.first_extern_index).contains(&index) {
324 Some(RegionClassification::Global)
325 } else if (self.first_extern_index..self.first_local_index).contains(&index) {
326 Some(RegionClassification::External)
327 } else if (self.first_local_index..self.num_universals).contains(&index) {
328 Some(RegionClassification::Local)
329 } else {
330 None
331 }
332 }
333
334 pub(crate) fn universal_regions_iter(&self) -> impl Iterator<Item = RegionVid> + 'static {
337 (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize)
338 }
339
340 pub(crate) fn is_local_free_region(&self, r: RegionVid) -> bool {
342 self.region_classification(r) == Some(RegionClassification::Local)
343 }
344
345 pub(crate) fn len(&self) -> usize {
347 self.num_universals
348 }
349
350 pub(crate) fn num_global_and_external_regions(&self) -> usize {
356 self.first_local_index
357 }
358
359 pub(crate) fn named_universal_regions_iter(
361 &self,
362 ) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> {
363 self.indices.indices.iter().map(|(&r, &v)| (r, v))
364 }
365
366 pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
368 self.indices.to_region_vid(r)
369 }
370
371 pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diag<'_, ()>) {
378 match self.defining_ty {
379 DefiningTy::Closure(def_id, args) => {
380 let v = with_no_trimmed_paths!(
381 args[tcx.generics_of(def_id).parent_count..]
382 .iter()
383 .map(|arg| arg.to_string())
384 .collect::<Vec<_>>()
385 );
386 err.note(format!(
387 "defining type: {} with closure args [\n {},\n]",
388 tcx.def_path_str_with_args(def_id, args),
389 v.join(",\n "),
390 ));
391
392 for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
398 err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
399 });
400 }
401 DefiningTy::CoroutineClosure(..) => {
402 todo!()
403 }
404 DefiningTy::Coroutine(def_id, args) => {
405 let v = with_no_trimmed_paths!(
406 args[tcx.generics_of(def_id).parent_count..]
407 .iter()
408 .map(|arg| arg.to_string())
409 .collect::<Vec<_>>()
410 );
411 err.note(format!(
412 "defining type: {} with coroutine args [\n {},\n]",
413 tcx.def_path_str_with_args(def_id, args),
414 v.join(",\n "),
415 ));
416
417 for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
421 err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
422 });
423 }
424 DefiningTy::FnDef(def_id, args) => {
425 err.note(format!("defining type: {}", tcx.def_path_str_with_args(def_id, args),));
426 }
427 DefiningTy::Const(def_id, args) => {
428 err.note(format!(
429 "defining constant type: {}",
430 tcx.def_path_str_with_args(def_id, args),
431 ));
432 }
433 DefiningTy::InlineConst(def_id, args) => {
434 err.note(format!(
435 "defining inline constant type: {}",
436 tcx.def_path_str_with_args(def_id, args),
437 ));
438 }
439 DefiningTy::GlobalAsm(_) => unreachable!(),
440 }
441 }
442
443 pub(crate) fn implicit_region_bound(&self) -> RegionVid {
444 self.fr_fn_body
445 }
446
447 pub(crate) fn encountered_re_error(&self) -> Option<ErrorGuaranteed> {
448 self.indices.encountered_re_error.get()
449 }
450}
451
452struct UniversalRegionsBuilder<'infcx, 'tcx> {
453 infcx: &'infcx BorrowckInferCtxt<'tcx>,
454 mir_def: LocalDefId,
455}
456
457impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
458 fn build(self) -> UniversalRegions<'tcx> {
459 debug!("build(mir_def={:?})", self.mir_def);
460
461 let param_env = self.infcx.param_env;
462 debug!("build: param_env={:?}", param_env);
463
464 assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars());
465
466 let fr_static = self
468 .infcx
469 .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
470 RegionCtxt::Free(kw::Static)
471 })
472 .as_var();
473
474 let first_extern_index = self.infcx.num_region_vars();
477
478 let defining_ty = self.defining_ty();
479 debug!("build: defining_ty={:?}", defining_ty);
480
481 let mut indices = self.compute_indices(fr_static, defining_ty);
482 debug!("build: indices={:?}", indices);
483
484 let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id());
485
486 let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id {
490 first_extern_index
491 } else {
492 for_each_late_bound_region_in_recursive_scope(
499 self.infcx.tcx,
500 self.infcx.tcx.local_parent(self.mir_def),
501 |r| {
502 debug!(?r);
503 let region_vid = {
504 let name = r.get_name_or_anon(self.infcx.tcx);
505 self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
506 RegionCtxt::LateBound(name)
507 })
508 };
509
510 debug!(?region_vid);
511 indices.insert_late_bound_region(r, region_vid.as_var());
512 },
513 );
514
515 self.infcx.num_region_vars()
518 };
519
520 let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
527 for (idx, bound_var) in bound_inputs_and_output.bound_vars().iter().enumerate() {
528 if let ty::BoundVariableKind::Region(kind) = bound_var {
529 let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
530 let r = ty::Region::new_late_param(self.infcx.tcx, self.mir_def.to_def_id(), kind);
531 let region_vid = {
532 let name = r.get_name_or_anon(self.infcx.tcx);
533 self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
534 RegionCtxt::LateBound(name)
535 })
536 };
537
538 debug!(?region_vid);
539 indices.insert_late_bound_region(r, region_vid.as_var());
540 }
541 }
542 let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
543 self.mir_def,
544 bound_inputs_and_output,
545 &indices,
546 );
547
548 let (unnormalized_output_ty, mut unnormalized_input_tys) =
549 inputs_and_output.split_last().unwrap();
550
551 if let DefiningTy::FnDef(def_id, _) = defining_ty {
554 if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() {
555 let va_list_did = self
556 .infcx
557 .tcx
558 .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def));
559
560 let reg_vid = self
561 .infcx
562 .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
563 RegionCtxt::Free(sym::c_dash_variadic)
564 })
565 .as_var();
566
567 let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
568 let va_list_ty = self
569 .infcx
570 .tcx
571 .type_of(va_list_did)
572 .instantiate(self.infcx.tcx, &[region.into()]);
573
574 unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
575 unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
576 );
577 }
578 }
579
580 let fr_fn_body = self
581 .infcx
582 .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
583 RegionCtxt::Free(sym::fn_body)
584 })
585 .as_var();
586
587 let num_universals = self.infcx.num_region_vars();
588
589 debug!("build: global regions = {}..{}", FIRST_GLOBAL_INDEX, first_extern_index);
590 debug!("build: extern regions = {}..{}", first_extern_index, first_local_index);
591 debug!("build: local regions = {}..{}", first_local_index, num_universals);
592
593 let (resume_ty, yield_ty) = match defining_ty {
594 DefiningTy::Coroutine(_, args) => {
595 let tys = args.as_coroutine();
596 (Some(tys.resume_ty()), Some(tys.yield_ty()))
597 }
598 _ => (None, None),
599 };
600
601 UniversalRegions {
602 indices,
603 fr_static,
604 fr_fn_body,
605 first_extern_index,
606 first_local_index,
607 num_universals,
608 defining_ty,
609 unnormalized_output_ty: *unnormalized_output_ty,
610 unnormalized_input_tys,
611 yield_ty,
612 resume_ty,
613 }
614 }
615
616 fn defining_ty(&self) -> DefiningTy<'tcx> {
619 let tcx = self.infcx.tcx;
620 let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
621
622 match tcx.hir_body_owner_kind(self.mir_def) {
623 BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
624 let defining_ty = tcx.type_of(self.mir_def).instantiate_identity();
625
626 debug!("defining_ty (pre-replacement): {:?}", defining_ty);
627
628 let defining_ty = self.infcx.replace_free_regions_with_nll_infer_vars(
629 NllRegionVariableOrigin::FreeRegion,
630 defining_ty,
631 );
632
633 match *defining_ty.kind() {
634 ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
635 ty::Coroutine(def_id, args) => DefiningTy::Coroutine(def_id, args),
636 ty::CoroutineClosure(def_id, args) => {
637 DefiningTy::CoroutineClosure(def_id, args)
638 }
639 ty::FnDef(def_id, args) => DefiningTy::FnDef(def_id, args),
640 _ => span_bug!(
641 tcx.def_span(self.mir_def),
642 "expected defining type for `{:?}`: `{:?}`",
643 self.mir_def,
644 defining_ty
645 ),
646 }
647 }
648
649 BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => {
650 let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
651 if self.mir_def.to_def_id() == typeck_root_def_id
652 && DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id))
654 {
655 let args = self.infcx.replace_free_regions_with_nll_infer_vars(
656 NllRegionVariableOrigin::FreeRegion,
657 identity_args,
658 );
659 DefiningTy::Const(self.mir_def.to_def_id(), args)
660 } else {
661 let ty = tcx
671 .typeck(self.mir_def)
672 .node_type(tcx.local_def_id_to_hir_id(self.mir_def));
673 let args = InlineConstArgs::new(
674 tcx,
675 InlineConstArgsParts { parent_args: identity_args, ty },
676 )
677 .args;
678 let args = self.infcx.replace_free_regions_with_nll_infer_vars(
679 NllRegionVariableOrigin::FreeRegion,
680 args,
681 );
682 DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
683 }
684 }
685
686 BodyOwnerKind::GlobalAsm => DefiningTy::GlobalAsm(self.mir_def.to_def_id()),
687 }
688 }
689
690 fn compute_indices(
695 &self,
696 fr_static: RegionVid,
697 defining_ty: DefiningTy<'tcx>,
698 ) -> UniversalRegionIndices<'tcx> {
699 let tcx = self.infcx.tcx;
700 let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
701 let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
702 let fr_args = match defining_ty {
703 DefiningTy::Closure(_, args)
704 | DefiningTy::CoroutineClosure(_, args)
705 | DefiningTy::Coroutine(_, args)
706 | DefiningTy::InlineConst(_, args) => {
707 assert!(args.len() >= identity_args.len());
715 assert_eq!(args.regions().count(), identity_args.regions().count());
716 args
717 }
718
719 DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
720
721 DefiningTy::GlobalAsm(_) => ty::List::empty(),
722 };
723
724 let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
725 let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
726
727 UniversalRegionIndices {
728 indices: global_mapping.chain(arg_mapping).collect(),
729 fr_static,
730 encountered_re_error: Cell::new(None),
731 }
732 }
733
734 fn compute_inputs_and_output(
735 &self,
736 indices: &UniversalRegionIndices<'tcx>,
737 defining_ty: DefiningTy<'tcx>,
738 ) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
739 let tcx = self.infcx.tcx;
740
741 let inputs_and_output = match defining_ty {
742 DefiningTy::Closure(def_id, args) => {
743 assert_eq!(self.mir_def.to_def_id(), def_id);
744 let closure_sig = args.as_closure().sig();
745 let inputs_and_output = closure_sig.inputs_and_output();
746 let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
747 inputs_and_output.bound_vars().iter().chain(iter::once(
748 ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv),
749 )),
750 );
751 let br = ty::BoundRegion {
752 var: ty::BoundVar::from_usize(bound_vars.len() - 1),
753 kind: ty::BoundRegionKind::ClosureEnv,
754 };
755 let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br);
756 let closure_ty = tcx.closure_env_ty(
757 Ty::new_closure(tcx, def_id, args),
758 args.as_closure().kind(),
759 env_region,
760 );
761
762 let (&output, tuplized_inputs) =
766 inputs_and_output.skip_binder().split_last().unwrap();
767 assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs");
768 let &ty::Tuple(inputs) = tuplized_inputs[0].kind() else {
769 bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]);
770 };
771
772 ty::Binder::bind_with_vars(
773 tcx.mk_type_list_from_iter(
774 iter::once(closure_ty).chain(inputs).chain(iter::once(output)),
775 ),
776 bound_vars,
777 )
778 }
779
780 DefiningTy::Coroutine(def_id, args) => {
781 assert_eq!(self.mir_def.to_def_id(), def_id);
782 let resume_ty = args.as_coroutine().resume_ty();
783 let output = args.as_coroutine().return_ty();
784 let coroutine_ty = Ty::new_coroutine(tcx, def_id, args);
785 let inputs_and_output =
786 self.infcx.tcx.mk_type_list(&[coroutine_ty, resume_ty, output]);
787 ty::Binder::dummy(inputs_and_output)
788 }
789
790 DefiningTy::CoroutineClosure(def_id, args) => {
799 assert_eq!(self.mir_def.to_def_id(), def_id);
800 let closure_sig = args.as_coroutine_closure().coroutine_closure_sig();
801 let bound_vars =
802 tcx.mk_bound_variable_kinds_from_iter(closure_sig.bound_vars().iter().chain(
803 iter::once(ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv)),
804 ));
805 let br = ty::BoundRegion {
806 var: ty::BoundVar::from_usize(bound_vars.len() - 1),
807 kind: ty::BoundRegionKind::ClosureEnv,
808 };
809 let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br);
810 let closure_kind = args.as_coroutine_closure().kind();
811
812 let closure_ty = tcx.closure_env_ty(
813 Ty::new_coroutine_closure(tcx, def_id, args),
814 closure_kind,
815 env_region,
816 );
817
818 let inputs = closure_sig.skip_binder().tupled_inputs_ty.tuple_fields();
819 let output = closure_sig.skip_binder().to_coroutine_given_kind_and_upvars(
820 tcx,
821 args.as_coroutine_closure().parent_args(),
822 tcx.coroutine_for_closure(def_id),
823 closure_kind,
824 env_region,
825 args.as_coroutine_closure().tupled_upvars_ty(),
826 args.as_coroutine_closure().coroutine_captures_by_ref_ty(),
827 );
828
829 ty::Binder::bind_with_vars(
830 tcx.mk_type_list_from_iter(
831 iter::once(closure_ty).chain(inputs).chain(iter::once(output)),
832 ),
833 bound_vars,
834 )
835 }
836
837 DefiningTy::FnDef(def_id, _) => {
838 let sig = tcx.fn_sig(def_id).instantiate_identity();
839 let sig = indices.fold_to_region_vids(tcx, sig);
840 sig.inputs_and_output()
841 }
842
843 DefiningTy::Const(def_id, _) => {
844 assert_eq!(self.mir_def.to_def_id(), def_id);
847 let ty = tcx.type_of(self.mir_def).instantiate_identity();
848
849 let ty = indices.fold_to_region_vids(tcx, ty);
850 ty::Binder::dummy(tcx.mk_type_list(&[ty]))
851 }
852
853 DefiningTy::InlineConst(def_id, args) => {
854 assert_eq!(self.mir_def.to_def_id(), def_id);
855 let ty = args.as_inline_const().ty();
856 ty::Binder::dummy(tcx.mk_type_list(&[ty]))
857 }
858
859 DefiningTy::GlobalAsm(def_id) => {
860 ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()]))
861 }
862 };
863
864 if let Err(terr) = inputs_and_output.skip_binder().error_reported() {
866 self.infcx.set_tainted_by_errors(terr);
867 }
868
869 inputs_and_output
870 }
871}
872
873#[extension(trait InferCtxtExt<'tcx>)]
874impl<'tcx> BorrowckInferCtxt<'tcx> {
875 #[instrument(skip(self), level = "debug")]
876 fn replace_free_regions_with_nll_infer_vars<T>(
877 &self,
878 origin: NllRegionVariableOrigin<'tcx>,
879 value: T,
880 ) -> T
881 where
882 T: TypeFoldable<TyCtxt<'tcx>>,
883 {
884 fold_regions(self.infcx.tcx, value, |region, _depth| {
885 let name = region.get_name_or_anon(self.infcx.tcx);
886 debug!(?region, ?name);
887
888 self.next_nll_region_var(origin, || RegionCtxt::Free(name))
889 })
890 }
891
892 #[instrument(level = "debug", skip(self, indices))]
893 fn replace_bound_regions_with_nll_infer_vars<T>(
894 &self,
895 all_outlive_scope: LocalDefId,
896 value: ty::Binder<'tcx, T>,
897 indices: &UniversalRegionIndices<'tcx>,
898 ) -> T
899 where
900 T: TypeFoldable<TyCtxt<'tcx>>,
901 {
902 let (value, _map) = self.tcx.instantiate_bound_regions(value, |br| {
903 debug!(?br);
904 let kind = ty::LateParamRegionKind::from_bound(br.var, br.kind);
905 let liberated_region =
906 ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), kind);
907 ty::Region::new_var(self.tcx, indices.to_region_vid(liberated_region))
908 });
909 value
910 }
911}
912
913impl<'tcx> UniversalRegionIndices<'tcx> {
914 fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) {
920 debug!("insert_late_bound_region({:?}, {:?})", r, vid);
921 assert_eq!(self.indices.insert(r, vid), None);
922 }
923
924 fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
937 match r.kind() {
938 ty::ReVar(..) => r.as_var(),
939 ty::ReError(guar) => {
940 self.encountered_re_error.set(Some(guar));
941 self.fr_static
945 }
946 _ => *self
947 .indices
948 .get(&r)
949 .unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r)),
950 }
951 }
952
953 fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
956 where
957 T: TypeFoldable<TyCtxt<'tcx>>,
958 {
959 fold_regions(tcx, value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region)))
960 }
961}
962
963fn for_each_late_bound_region_in_recursive_scope<'tcx>(
967 tcx: TyCtxt<'tcx>,
968 mut mir_def_id: LocalDefId,
969 mut f: impl FnMut(ty::Region<'tcx>),
970) {
971 let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id());
972
973 loop {
975 for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f);
976
977 if mir_def_id.to_def_id() == typeck_root_def_id {
978 break;
979 } else {
980 mir_def_id = tcx.local_parent(mir_def_id);
981 }
982 }
983}
984
985fn for_each_late_bound_region_in_item<'tcx>(
989 tcx: TyCtxt<'tcx>,
990 mir_def_id: LocalDefId,
991 mut f: impl FnMut(ty::Region<'tcx>),
992) {
993 let bound_vars = match tcx.def_kind(mir_def_id) {
994 DefKind::Fn | DefKind::AssocFn => {
995 tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id))
996 }
997 DefKind::Closure => {
1001 let ty = tcx.type_of(mir_def_id).instantiate_identity();
1002 match *ty.kind() {
1003 ty::Closure(_, args) => args.as_closure().sig().bound_vars(),
1004 ty::CoroutineClosure(_, args) => {
1005 args.as_coroutine_closure().coroutine_closure_sig().bound_vars()
1006 }
1007 ty::Coroutine(_, _) | ty::Error(_) => return,
1008 _ => unreachable!("unexpected type for closure: {ty}"),
1009 }
1010 }
1011 _ => return,
1012 };
1013
1014 for (idx, bound_var) in bound_vars.iter().enumerate() {
1015 if let ty::BoundVariableKind::Region(kind) = bound_var {
1016 let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
1017 let liberated_region = ty::Region::new_late_param(tcx, mir_def_id.to_def_id(), kind);
1018 f(liberated_region);
1019 }
1020 }
1021}