@@ -272,6 +272,13 @@ pub struct RegionMaps {
272272 /// block (see `terminating_scopes`).
273273 rvalue_scopes : RefCell < NodeMap < CodeExtent > > ,
274274
275+ /// Records the value of rvalue scopes before they were shrunk by
276+ /// #36082, for error reporting.
277+ ///
278+ /// FIXME: this should be temporary. Remove this by 1.18.0 or
279+ /// so.
280+ shrunk_rvalue_scopes : RefCell < NodeMap < CodeExtent > > ,
281+
275282 /// Encodes the hierarchy of fn bodies. Every fn body (including
276283 /// closures) forms its own distinct region hierarchy, rooted in
277284 /// the block that is the fn body. This map points from the id of
@@ -419,11 +426,7 @@ impl RegionMaps {
419426 e ( child, parent)
420427 }
421428 }
422- pub fn each_rvalue_scope < E > ( & self , mut e : E ) where E : FnMut ( & ast:: NodeId , & CodeExtent ) {
423- for ( child, parent) in self . rvalue_scopes . borrow ( ) . iter ( ) {
424- e ( child, parent)
425- }
426- }
429+
427430 /// Records that `sub_fn` is defined within `sup_fn`. These ids
428431 /// should be the id of the block that is the fn body, which is
429432 /// also the root of the region hierarchy for that fn.
@@ -457,6 +460,12 @@ impl RegionMaps {
457460 self . rvalue_scopes . borrow_mut ( ) . insert ( var, lifetime) ;
458461 }
459462
463+ fn record_shrunk_rvalue_scope ( & self , var : ast:: NodeId , lifetime : CodeExtent ) {
464+ debug ! ( "record_rvalue_scope(sub={:?}, sup={:?})" , var, lifetime) ;
465+ assert ! ( var != lifetime. node_id( self ) ) ;
466+ self . shrunk_rvalue_scopes . borrow_mut ( ) . insert ( var, lifetime) ;
467+ }
468+
460469 pub fn opt_encl_scope ( & self , id : CodeExtent ) -> Option < CodeExtent > {
461470 //! Returns the narrowest scope that encloses `id`, if any.
462471 self . scope_map . borrow ( ) [ id. 0 as usize ] . into_option ( )
@@ -476,6 +485,30 @@ impl RegionMaps {
476485 }
477486 }
478487
488+ pub fn temporary_scope2 ( & self , expr_id : ast:: NodeId ) -> ( Option < CodeExtent > , bool ) {
489+ let temporary_scope = self . temporary_scope ( expr_id) ;
490+ let was_shrunk = match self . shrunk_rvalue_scopes . borrow ( ) . get ( & expr_id) {
491+ Some ( & s) => {
492+ info ! ( "temporary_scope2({:?}, scope={:?}, shrunk={:?})" ,
493+ expr_id, temporary_scope, s) ;
494+ temporary_scope != Some ( s)
495+ }
496+ _ => false
497+ } ;
498+ info ! ( "temporary_scope2({:?}) - was_shrunk={:?}" , expr_id, was_shrunk) ;
499+ ( temporary_scope, was_shrunk)
500+ }
501+
502+ pub fn old_and_new_temporary_scope ( & self , expr_id : ast:: NodeId ) ->
503+ ( Option < CodeExtent > , Option < CodeExtent > )
504+ {
505+ let temporary_scope = self . temporary_scope ( expr_id) ;
506+ ( temporary_scope,
507+ self . shrunk_rvalue_scopes
508+ . borrow ( ) . get ( & expr_id) . cloned ( )
509+ . or ( temporary_scope) )
510+ }
511+
479512 pub fn temporary_scope ( & self , expr_id : ast:: NodeId ) -> Option < CodeExtent > {
480513 //! Returns the scope when temp created by expr_id will be cleaned up
481514
@@ -929,8 +962,10 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
929962 let is_borrow =
930963 if let Some ( ref ty) = local. ty { is_borrowed_ty ( & ty) } else { false } ;
931964
932- if is_binding_pat ( & local. pat ) || is_borrow {
933- record_rvalue_scope ( visitor, & expr, blk_scope) ;
965+ if is_binding_pat ( & local. pat ) {
966+ record_rvalue_scope ( visitor, & expr, blk_scope, false ) ;
967+ } else if is_borrow {
968+ record_rvalue_scope ( visitor, & expr, blk_scope, true ) ;
934969 }
935970 }
936971
@@ -995,7 +1030,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
9951030 match expr. node {
9961031 hir:: ExprAddrOf ( _, ref subexpr) => {
9971032 record_rvalue_scope_if_borrow_expr ( visitor, & subexpr, blk_id) ;
998- record_rvalue_scope ( visitor, & subexpr, blk_id) ;
1033+ record_rvalue_scope ( visitor, & subexpr, blk_id, false ) ;
9991034 }
10001035 hir:: ExprStruct ( _, ref fields, _) => {
10011036 for field in fields {
@@ -1040,15 +1075,21 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
10401075 /// Note: ET is intended to match "rvalues or lvalues based on rvalues".
10411076 fn record_rvalue_scope < ' a > ( visitor : & mut RegionResolutionVisitor ,
10421077 expr : & ' a hir:: Expr ,
1043- blk_scope : CodeExtent ) {
1078+ blk_scope : CodeExtent ,
1079+ is_shrunk : bool ) {
10441080 let mut expr = expr;
10451081 loop {
10461082 // Note: give all the expressions matching `ET` with the
10471083 // extended temporary lifetime, not just the innermost rvalue,
10481084 // because in trans if we must compile e.g. `*rvalue()`
10491085 // into a temporary, we request the temporary scope of the
10501086 // outer expression.
1051- visitor. region_maps . record_rvalue_scope ( expr. id , blk_scope) ;
1087+ if is_shrunk {
1088+ // this changed because of #36082
1089+ visitor. region_maps . record_shrunk_rvalue_scope ( expr. id , blk_scope) ;
1090+ } else {
1091+ visitor. region_maps . record_rvalue_scope ( expr. id , blk_scope) ;
1092+ }
10521093
10531094 match expr. node {
10541095 hir:: ExprAddrOf ( _, ref subexpr) |
@@ -1225,6 +1266,7 @@ pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps {
12251266 scope_map : RefCell :: new ( vec ! [ ] ) ,
12261267 var_map : RefCell :: new ( NodeMap ( ) ) ,
12271268 rvalue_scopes : RefCell :: new ( NodeMap ( ) ) ,
1269+ shrunk_rvalue_scopes : RefCell :: new ( NodeMap ( ) ) ,
12281270 fn_tree : RefCell :: new ( NodeMap ( ) ) ,
12291271 } ;
12301272 let root_extent = maps. bogus_code_extent (
0 commit comments