@@ -198,6 +198,14 @@ impl CodeExtentData {
198
198
199
199
/// The region maps encode information about region relationships.
200
200
pub struct RegionMaps < ' tcx > {
201
+ /// If not empty, this body is the root of this region hierarchy.
202
+ root_body : Option < hir:: BodyId > ,
203
+
204
+ /// The parent of the root body owner, if the latter is an
205
+ /// an associated const or method, as impls/traits can also
206
+ /// have lifetime parameters free in this body.
207
+ root_parent : Option < ast:: NodeId > ,
208
+
201
209
/// `scope_map` maps from a scope id to the enclosing scope id;
202
210
/// this is usually corresponding to the lexical nesting, though
203
211
/// in the case of closures the parent scope is the innermost
@@ -295,6 +303,8 @@ struct RegionResolutionVisitor<'a, 'tcx: 'a> {
295
303
impl < ' tcx > RegionMaps < ' tcx > {
296
304
pub fn new ( ) -> Self {
297
305
RegionMaps {
306
+ root_body : None ,
307
+ root_parent : None ,
298
308
scope_map : FxHashMap ( ) ,
299
309
destruction_scopes : FxHashMap ( ) ,
300
310
var_map : NodeMap ( ) ,
@@ -600,8 +610,39 @@ impl<'tcx> RegionMaps<'tcx> {
600
610
/// returns the outermost `CodeExtent` that the region outlives.
601
611
pub fn free_extent < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > , fr : & ty:: FreeRegion )
602
612
-> CodeExtent < ' tcx > {
603
- let scope_id = tcx. hir . as_local_node_id ( fr. scope ) . unwrap ( ) ;
604
- tcx. call_site_extent ( scope_id)
613
+ let param_owner = match fr. bound_region {
614
+ ty:: BoundRegion :: BrNamed ( def_id, _) => {
615
+ tcx. parent_def_id ( def_id) . unwrap ( )
616
+ }
617
+ _ => fr. scope
618
+ } ;
619
+
620
+ let param_owner_id = tcx. hir . as_local_node_id ( param_owner) . unwrap ( ) ;
621
+ let body_id = tcx. hir . maybe_body_owned_by ( param_owner_id)
622
+ . map ( |body| {
623
+ assert_eq ! ( param_owner, fr. scope) ;
624
+ body
625
+ } )
626
+ . unwrap_or_else ( || {
627
+ let root = tcx. hir . as_local_node_id ( fr. scope ) . unwrap ( ) ;
628
+
629
+ assert_eq ! ( Some ( param_owner_id) , self . root_parent,
630
+ "free_extent: {:?} not recognized by the region maps for {:?}" ,
631
+ param_owner, fr. scope) ;
632
+
633
+ let root_body = tcx. hir . body_owned_by ( root) ;
634
+
635
+ assert ! ( Some ( root_body) == self . root_body,
636
+ "free_extent: {:?} not inside {:?}" ,
637
+ param_owner, self . root_body. map( |body| tcx. hir. body_owner_def_id( body) ) ) ;
638
+
639
+ root_body
640
+ } ) ;
641
+
642
+ tcx. intern_code_extent ( CodeExtentData :: CallSiteScope {
643
+ fn_id : tcx. hir . body_owner ( body_id) ,
644
+ body_id : body_id. node_id
645
+ } )
605
646
}
606
647
}
607
648
@@ -1167,6 +1208,19 @@ fn region_maps<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
1167
1208
1168
1209
let id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
1169
1210
if let Some ( body) = tcx. hir . maybe_body_owned_by ( id) {
1211
+ maps. root_body = Some ( body) ;
1212
+
1213
+ // If the item is an associated const or a method,
1214
+ // record its impl/trait parent, as it can also have
1215
+ // lifetime parameters free in this body.
1216
+ match tcx. hir . get ( id) {
1217
+ hir:: map:: NodeImplItem ( _) |
1218
+ hir:: map:: NodeTraitItem ( _) => {
1219
+ maps. root_parent = Some ( tcx. hir . get_parent ( id) ) ;
1220
+ }
1221
+ _ => { }
1222
+ }
1223
+
1170
1224
let mut visitor = RegionResolutionVisitor {
1171
1225
tcx : tcx,
1172
1226
region_maps : & mut maps,
0 commit comments