@@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId};
22
22
use rustc_index:: vec:: { Idx , IndexVec } ;
23
23
use rustc_infer:: infer:: { InferCtxt , NllRegionVariableOrigin } ;
24
24
use 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
+ } ;
26
28
use rustc_middle:: ty:: { InternalSubsts , SubstsRef } ;
27
29
use std:: iter;
28
30
@@ -241,15 +243,15 @@ impl<'tcx> UniversalRegions<'tcx> {
241
243
tcx : TyCtxt < ' tcx > ,
242
244
closure_substs : SubstsRef < ' tcx > ,
243
245
expected_num_vars : usize ,
244
- typeck_root_def_id : DefId ,
246
+ closure_def_id : LocalDefId ,
245
247
) -> IndexVec < RegionVid , ty:: Region < ' tcx > > {
246
248
let mut region_mapping = IndexVec :: with_capacity ( expected_num_vars) ;
247
249
region_mapping. push ( tcx. lifetimes . re_static ) ;
248
250
tcx. for_each_free_region ( & closure_substs, |fr| {
249
251
region_mapping. push ( fr) ;
250
252
} ) ;
251
253
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| {
253
255
region_mapping. push ( r) ;
254
256
} ) ;
255
257
@@ -339,9 +341,8 @@ impl<'tcx> UniversalRegions<'tcx> {
339
341
// tests, and the resulting print-outs include def-ids
340
342
// and other things that are not stable across tests!
341
343
// 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) ) ) ;
345
346
} ) ;
346
347
}
347
348
DefiningTy :: Generator ( def_id, substs, _) => {
@@ -354,9 +355,8 @@ impl<'tcx> UniversalRegions<'tcx> {
354
355
// FIXME: As above, we'd like to print out the region
355
356
// `r` but doing so is not stable across architectures
356
357
// 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) ) ) ;
360
360
} ) ;
361
361
}
362
362
DefiningTy :: FnDef ( def_id, substs) => {
@@ -421,13 +421,24 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
421
421
first_extern_index
422
422
} else {
423
423
// 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
425
425
// to the closure c (although it is local to the fn foo):
426
426
// fn foo<'a>() {
427
427
// let c = || { let x: &'a u32 = ...; }
428
428
// }
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
+
431
442
// Any regions created during the execution of `defining_ty` or during the above
432
443
// late-bound region replacement are all considered 'extern' regions
433
444
self . infcx . num_region_vars ( )
@@ -444,12 +455,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
444
455
bound_inputs_and_output,
445
456
& mut indices,
446
457
) ;
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
+ } ) ;
453
468
454
469
let ( unnormalized_output_ty, mut unnormalized_input_tys) =
455
470
inputs_and_output. split_last ( ) . unwrap ( ) ;
@@ -692,7 +707,13 @@ trait InferCtxtExt<'tcx> {
692
707
where
693
708
T : TypeFoldable < ' tcx > ;
694
709
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 (
696
717
& self ,
697
718
mir_def_id : LocalDefId ,
698
719
indices : & mut UniversalRegionIndices < ' tcx > ,
@@ -746,13 +767,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
746
767
/// set of late-bound regions and checks for any that we have not yet seen, adding them to the
747
768
/// inputs vector.
748
769
#[ 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 (
750
787
& self ,
751
788
mir_def_id : LocalDefId ,
752
789
indices : & mut UniversalRegionIndices < ' tcx > ,
753
790
) {
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| {
756
792
debug ! ( ?r) ;
757
793
if !indices. indices . contains_key ( & r) {
758
794
let region_vid = self . next_nll_region_var ( FR ) ;
@@ -803,21 +839,44 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
803
839
}
804
840
}
805
841
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 > (
809
846
tcx : TyCtxt < ' tcx > ,
810
- fn_def_id : DefId ,
847
+ mut mir_def_id : LocalDefId ,
811
848
mut f : impl FnMut ( ty:: Region < ' tcx > ) ,
812
849
) {
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) ;
821
860
}
822
861
}
823
862
}
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