@@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId};
2222use rustc_index:: vec:: { Idx , IndexVec } ;
2323use rustc_infer:: infer:: { InferCtxt , NllRegionVariableOrigin } ;
2424use rustc_middle:: ty:: fold:: TypeFoldable ;
25- use rustc_middle:: ty:: { self , InlineConstSubsts , InlineConstSubstsParts , RegionVid , Ty , TyCtxt } ;
25+ use rustc_middle:: ty:: {
26+ self , DefIdTree , InlineConstSubsts , InlineConstSubstsParts , RegionVid , Ty , TyCtxt ,
27+ } ;
2628use rustc_middle:: ty:: { InternalSubsts , SubstsRef } ;
2729use std:: iter;
2830
@@ -241,15 +243,15 @@ impl<'tcx> UniversalRegions<'tcx> {
241243 tcx : TyCtxt < ' tcx > ,
242244 closure_substs : SubstsRef < ' tcx > ,
243245 expected_num_vars : usize ,
244- typeck_root_def_id : DefId ,
246+ closure_def_id : LocalDefId ,
245247 ) -> IndexVec < RegionVid , ty:: Region < ' tcx > > {
246248 let mut region_mapping = IndexVec :: with_capacity ( expected_num_vars) ;
247249 region_mapping. push ( tcx. lifetimes . re_static ) ;
248250 tcx. for_each_free_region ( & closure_substs, |fr| {
249251 region_mapping. push ( fr) ;
250252 } ) ;
251253
252- for_each_late_bound_region_defined_on ( tcx, typeck_root_def_id , |r| {
254+ for_each_late_bound_region_in_recursive_scope ( tcx, tcx . local_parent ( closure_def_id ) , |r| {
253255 region_mapping. push ( r) ;
254256 } ) ;
255257
@@ -339,9 +341,8 @@ impl<'tcx> UniversalRegions<'tcx> {
339341 // tests, and the resulting print-outs include def-ids
340342 // and other things that are not stable across tests!
341343 // So we just include the region-vid. Annoying.
342- let typeck_root_def_id = tcx. typeck_root_def_id ( def_id) ;
343- for_each_late_bound_region_defined_on ( tcx, typeck_root_def_id, |r| {
344- err. note ( & format ! ( "late-bound region is {:?}" , self . to_region_vid( r) , ) ) ;
344+ for_each_late_bound_region_in_recursive_scope ( tcx, def_id. expect_local ( ) , |r| {
345+ err. note ( & format ! ( "late-bound region is {:?}" , self . to_region_vid( r) ) ) ;
345346 } ) ;
346347 }
347348 DefiningTy :: Generator ( def_id, substs, _) => {
@@ -354,9 +355,8 @@ impl<'tcx> UniversalRegions<'tcx> {
354355 // FIXME: As above, we'd like to print out the region
355356 // `r` but doing so is not stable across architectures
356357 // and so forth.
357- let typeck_root_def_id = tcx. typeck_root_def_id ( def_id) ;
358- for_each_late_bound_region_defined_on ( tcx, typeck_root_def_id, |r| {
359- err. note ( & format ! ( "late-bound region is {:?}" , self . to_region_vid( r) , ) ) ;
358+ for_each_late_bound_region_in_recursive_scope ( tcx, def_id. expect_local ( ) , |r| {
359+ err. note ( & format ! ( "late-bound region is {:?}" , self . to_region_vid( r) ) ) ;
360360 } ) ;
361361 }
362362 DefiningTy :: FnDef ( def_id, substs) => {
@@ -421,13 +421,24 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
421421 first_extern_index
422422 } else {
423423 // If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
424- // function are actually external regions to us. For example, here, 'a is not local
424+ // function/closures are actually external regions to us. For example, here, 'a is not local
425425 // to the closure c (although it is local to the fn foo):
426426 // fn foo<'a>() {
427427 // let c = || { let x: &'a u32 = ...; }
428428 // }
429- self . infcx
430- . replace_late_bound_regions_with_nll_infer_vars ( self . mir_def . did , & mut indices) ;
429+ for_each_late_bound_region_in_recursive_scope (
430+ self . infcx . tcx ,
431+ self . infcx . tcx . local_parent ( self . mir_def . did ) ,
432+ |r| {
433+ debug ! ( ?r) ;
434+ if !indices. indices . contains_key ( & r) {
435+ let region_vid = self . infcx . next_nll_region_var ( FR ) ;
436+ debug ! ( ?region_vid) ;
437+ indices. insert_late_bound_region ( r, region_vid. to_region_vid ( ) ) ;
438+ }
439+ } ,
440+ ) ;
441+
431442 // Any regions created during the execution of `defining_ty` or during the above
432443 // late-bound region replacement are all considered 'extern' regions
433444 self . infcx . num_region_vars ( )
@@ -444,12 +455,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
444455 bound_inputs_and_output,
445456 & mut indices,
446457 ) ;
447- // Converse of above, if this is a function then the late-bound regions declared on its
448- // signature are local to the fn.
449- if self . mir_def . did . to_def_id ( ) == typeck_root_def_id {
450- self . infcx
451- . replace_late_bound_regions_with_nll_infer_vars ( self . mir_def . did , & mut indices) ;
452- }
458+ // Converse of above, if this is a function/closure then the late-bound regions declared on its
459+ // signature are local.
460+ for_each_late_bound_region_in_item ( self . infcx . tcx , self . mir_def . did , |r| {
461+ debug ! ( ?r) ;
462+ if !indices. indices . contains_key ( & r) {
463+ let region_vid = self . infcx . next_nll_region_var ( FR ) ;
464+ debug ! ( ?region_vid) ;
465+ indices. insert_late_bound_region ( r, region_vid. to_region_vid ( ) ) ;
466+ }
467+ } ) ;
453468
454469 let ( unnormalized_output_ty, mut unnormalized_input_tys) =
455470 inputs_and_output. split_last ( ) . unwrap ( ) ;
@@ -692,7 +707,13 @@ trait InferCtxtExt<'tcx> {
692707 where
693708 T : TypeFoldable < ' tcx > ;
694709
695- fn replace_late_bound_regions_with_nll_infer_vars (
710+ fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope (
711+ & self ,
712+ mir_def_id : LocalDefId ,
713+ indices : & mut UniversalRegionIndices < ' tcx > ,
714+ ) ;
715+
716+ fn replace_late_bound_regions_with_nll_infer_vars_in_item (
696717 & self ,
697718 mir_def_id : LocalDefId ,
698719 indices : & mut UniversalRegionIndices < ' tcx > ,
@@ -746,13 +767,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
746767 /// set of late-bound regions and checks for any that we have not yet seen, adding them to the
747768 /// inputs vector.
748769 #[ instrument( skip( self , indices) ) ]
749- fn replace_late_bound_regions_with_nll_infer_vars (
770+ fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope (
771+ & self ,
772+ mir_def_id : LocalDefId ,
773+ indices : & mut UniversalRegionIndices < ' tcx > ,
774+ ) {
775+ for_each_late_bound_region_in_recursive_scope ( self . tcx , mir_def_id, |r| {
776+ debug ! ( ?r) ;
777+ if !indices. indices . contains_key ( & r) {
778+ let region_vid = self . next_nll_region_var ( FR ) ;
779+ debug ! ( ?region_vid) ;
780+ indices. insert_late_bound_region ( r, region_vid. to_region_vid ( ) ) ;
781+ }
782+ } ) ;
783+ }
784+
785+ #[ instrument( skip( self , indices) ) ]
786+ fn replace_late_bound_regions_with_nll_infer_vars_in_item (
750787 & self ,
751788 mir_def_id : LocalDefId ,
752789 indices : & mut UniversalRegionIndices < ' tcx > ,
753790 ) {
754- let typeck_root_def_id = self . tcx . typeck_root_def_id ( mir_def_id. to_def_id ( ) ) ;
755- for_each_late_bound_region_defined_on ( self . tcx , typeck_root_def_id, |r| {
791+ for_each_late_bound_region_in_item ( self . tcx , mir_def_id, |r| {
756792 debug ! ( ?r) ;
757793 if !indices. indices . contains_key ( & r) {
758794 let region_vid = self . next_nll_region_var ( FR ) ;
@@ -803,21 +839,44 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
803839 }
804840}
805841
806- /// Iterates over the late-bound regions defined on fn_def_id and
807- /// invokes `f` with the liberated form of each one.
808- fn for_each_late_bound_region_defined_on < ' tcx > (
842+ /// Iterates over the late-bound regions defined on `mir_def_id` and all of its
843+ /// parents, up to the typeck root, and invokes `f` with the liberated form
844+ /// of each one.
845+ fn for_each_late_bound_region_in_recursive_scope < ' tcx > (
809846 tcx : TyCtxt < ' tcx > ,
810- fn_def_id : DefId ,
847+ mut mir_def_id : LocalDefId ,
811848 mut f : impl FnMut ( ty:: Region < ' tcx > ) ,
812849) {
813- if let Some ( late_bounds) = tcx. is_late_bound_map ( fn_def_id. expect_local ( ) ) {
814- for & region_def_id in late_bounds. iter ( ) {
815- let name = tcx. item_name ( region_def_id. to_def_id ( ) ) ;
816- let liberated_region = tcx. mk_region ( ty:: ReFree ( ty:: FreeRegion {
817- scope : fn_def_id,
818- bound_region : ty:: BoundRegionKind :: BrNamed ( region_def_id. to_def_id ( ) , name) ,
819- } ) ) ;
820- f ( liberated_region) ;
850+ let typeck_root_def_id = tcx. typeck_root_def_id ( mir_def_id. to_def_id ( ) ) ;
851+
852+ // Walk up the tree, collecting late-bound regions until we hit the typeck root
853+ loop {
854+ for_each_late_bound_region_in_item ( tcx, mir_def_id, & mut f) ;
855+
856+ if mir_def_id. to_def_id ( ) == typeck_root_def_id {
857+ break ;
858+ } else {
859+ mir_def_id = tcx. local_parent ( mir_def_id) ;
821860 }
822861 }
823862}
863+
864+ /// Iterates over the late-bound regions defined on `mir_def_id` and all of its
865+ /// parents, up to the typeck root, and invokes `f` with the liberated form
866+ /// of each one.
867+ fn for_each_late_bound_region_in_item < ' tcx > (
868+ tcx : TyCtxt < ' tcx > ,
869+ mir_def_id : LocalDefId ,
870+ mut f : impl FnMut ( ty:: Region < ' tcx > ) ,
871+ ) {
872+ if !tcx. def_kind ( mir_def_id) . is_fn_like ( ) {
873+ return ;
874+ }
875+
876+ for bound_var in tcx. late_bound_vars ( tcx. hir ( ) . local_def_id_to_hir_id ( mir_def_id) ) {
877+ let ty:: BoundVariableKind :: Region ( bound_region) = bound_var else { continue ; } ;
878+ let liberated_region = tcx
879+ . mk_region ( ty:: ReFree ( ty:: FreeRegion { scope : mir_def_id. to_def_id ( ) , bound_region } ) ) ;
880+ f ( liberated_region) ;
881+ }
882+ }
0 commit comments