@@ -272,6 +272,13 @@ pub struct RegionMaps {
272
272
/// block (see `terminating_scopes`).
273
273
rvalue_scopes : RefCell < NodeMap < CodeExtent > > ,
274
274
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
+
275
282
/// Encodes the hierarchy of fn bodies. Every fn body (including
276
283
/// closures) forms its own distinct region hierarchy, rooted in
277
284
/// the block that is the fn body. This map points from the id of
@@ -419,11 +426,7 @@ impl RegionMaps {
419
426
e ( child, parent)
420
427
}
421
428
}
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
+
427
430
/// Records that `sub_fn` is defined within `sup_fn`. These ids
428
431
/// should be the id of the block that is the fn body, which is
429
432
/// also the root of the region hierarchy for that fn.
@@ -457,6 +460,12 @@ impl RegionMaps {
457
460
self . rvalue_scopes . borrow_mut ( ) . insert ( var, lifetime) ;
458
461
}
459
462
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
+
460
469
pub fn opt_encl_scope ( & self , id : CodeExtent ) -> Option < CodeExtent > {
461
470
//! Returns the narrowest scope that encloses `id`, if any.
462
471
self . scope_map . borrow ( ) [ id. 0 as usize ] . into_option ( )
@@ -476,6 +485,30 @@ impl RegionMaps {
476
485
}
477
486
}
478
487
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
+
479
512
pub fn temporary_scope ( & self , expr_id : ast:: NodeId ) -> Option < CodeExtent > {
480
513
//! Returns the scope when temp created by expr_id will be cleaned up
481
514
@@ -929,8 +962,10 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
929
962
let is_borrow =
930
963
if let Some ( ref ty) = local. ty { is_borrowed_ty ( & ty) } else { false } ;
931
964
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 ) ;
934
969
}
935
970
}
936
971
@@ -995,7 +1030,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
995
1030
match expr. node {
996
1031
hir:: ExprAddrOf ( _, ref subexpr) => {
997
1032
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 ) ;
999
1034
}
1000
1035
hir:: ExprStruct ( _, ref fields, _) => {
1001
1036
for field in fields {
@@ -1040,15 +1075,21 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
1040
1075
/// Note: ET is intended to match "rvalues or lvalues based on rvalues".
1041
1076
fn record_rvalue_scope < ' a > ( visitor : & mut RegionResolutionVisitor ,
1042
1077
expr : & ' a hir:: Expr ,
1043
- blk_scope : CodeExtent ) {
1078
+ blk_scope : CodeExtent ,
1079
+ is_shrunk : bool ) {
1044
1080
let mut expr = expr;
1045
1081
loop {
1046
1082
// Note: give all the expressions matching `ET` with the
1047
1083
// extended temporary lifetime, not just the innermost rvalue,
1048
1084
// because in trans if we must compile e.g. `*rvalue()`
1049
1085
// into a temporary, we request the temporary scope of the
1050
1086
// 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
+ }
1052
1093
1053
1094
match expr. node {
1054
1095
hir:: ExprAddrOf ( _, ref subexpr) |
@@ -1225,6 +1266,7 @@ pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps {
1225
1266
scope_map : RefCell :: new ( vec ! [ ] ) ,
1226
1267
var_map : RefCell :: new ( NodeMap ( ) ) ,
1227
1268
rvalue_scopes : RefCell :: new ( NodeMap ( ) ) ,
1269
+ shrunk_rvalue_scopes : RefCell :: new ( NodeMap ( ) ) ,
1228
1270
fn_tree : RefCell :: new ( NodeMap ( ) ) ,
1229
1271
} ;
1230
1272
let root_extent = maps. bogus_code_extent (
0 commit comments