@@ -782,25 +782,8 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
782782 }
783783 self . enter_scope ( Scope { id, data : ScopeData :: Node } ) ;
784784 }
785- }
786-
787- impl < ' tcx > Visitor < ' tcx > for RegionResolutionVisitor < ' tcx > {
788- fn visit_block ( & mut self , b : & ' tcx Block < ' tcx > ) {
789- resolve_block ( self , b) ;
790- }
791-
792- fn visit_body ( & mut self , body : & ' tcx hir:: Body < ' tcx > ) {
793- let body_id = body. id ( ) ;
794- let owner_id = self . tcx . hir ( ) . body_owner_def_id ( body_id) ;
795-
796- debug ! (
797- "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})" ,
798- owner_id,
799- self . tcx. sess. source_map( ) . span_to_diagnostic_string( body. value. span) ,
800- body_id,
801- self . cx. parent
802- ) ;
803785
786+ fn enter_body ( & mut self , hir_id : hir:: HirId , f : impl FnOnce ( & mut Self ) ) {
804787 // Save all state that is specific to the outer function
805788 // body. These will be restored once down below, once we've
806789 // visited the body.
@@ -812,50 +795,73 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
812795 // control flow assumptions. This doesn't apply to nested
813796 // bodies within the `+=` statements. See #69307.
814797 let outer_pessimistic_yield = mem:: replace ( & mut self . pessimistic_yield , false ) ;
815- self . terminating_scopes . insert ( body. value . hir_id . local_id ) ;
816-
817- self . enter_scope ( Scope { id : body. value . hir_id . local_id , data : ScopeData :: CallSite } ) ;
818- self . enter_scope ( Scope { id : body. value . hir_id . local_id , data : ScopeData :: Arguments } ) ;
798+ self . terminating_scopes . insert ( hir_id. local_id ) ;
819799
820- // The arguments and `self` are parented to the fn.
821- self . cx . var_parent = self . cx . parent . take ( ) ;
822- for param in body. params {
823- self . visit_pat ( param. pat ) ;
824- }
800+ self . enter_scope ( Scope { id : hir_id. local_id , data : ScopeData :: CallSite } ) ;
801+ self . enter_scope ( Scope { id : hir_id. local_id , data : ScopeData :: Arguments } ) ;
825802
826- // The body of the every fn is a root scope.
827- self . cx . parent = self . cx . var_parent ;
828- if self . tcx . hir ( ) . body_owner_kind ( owner_id) . is_fn_or_closure ( ) {
829- self . visit_expr ( body. value )
830- } else {
831- // Only functions have an outer terminating (drop) scope, while
832- // temporaries in constant initializers may be 'static, but only
833- // according to rvalue lifetime semantics, using the same
834- // syntactical rules used for let initializers.
835- //
836- // e.g., in `let x = &f();`, the temporary holding the result from
837- // the `f()` call lives for the entirety of the surrounding block.
838- //
839- // Similarly, `const X: ... = &f();` would have the result of `f()`
840- // live for `'static`, implying (if Drop restrictions on constants
841- // ever get lifted) that the value *could* have a destructor, but
842- // it'd get leaked instead of the destructor running during the
843- // evaluation of `X` (if at all allowed by CTFE).
844- //
845- // However, `const Y: ... = g(&f());`, like `let y = g(&f());`,
846- // would *not* let the `f()` temporary escape into an outer scope
847- // (i.e., `'static`), which means that after `g` returns, it drops,
848- // and all the associated destruction scope rules apply.
849- self . cx . var_parent = None ;
850- resolve_local ( self , None , Some ( body. value ) ) ;
851- }
803+ f ( self ) ;
852804
853805 // Restore context we had at the start.
854806 self . expr_and_pat_count = outer_ec;
855807 self . cx = outer_cx;
856808 self . terminating_scopes = outer_ts;
857809 self . pessimistic_yield = outer_pessimistic_yield;
858810 }
811+ }
812+
813+ impl < ' tcx > Visitor < ' tcx > for RegionResolutionVisitor < ' tcx > {
814+ fn visit_block ( & mut self , b : & ' tcx Block < ' tcx > ) {
815+ resolve_block ( self , b) ;
816+ }
817+
818+ fn visit_body ( & mut self , body : & ' tcx hir:: Body < ' tcx > ) {
819+ let body_id = body. id ( ) ;
820+ let owner_id = self . tcx . hir ( ) . body_owner_def_id ( body_id) ;
821+
822+ debug ! (
823+ "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})" ,
824+ owner_id,
825+ self . tcx. sess. source_map( ) . span_to_diagnostic_string( body. value. span) ,
826+ body_id,
827+ self . cx. parent
828+ ) ;
829+
830+ self . enter_body ( body. value . hir_id , |this| {
831+ if this. tcx . hir ( ) . body_owner_kind ( owner_id) . is_fn_or_closure ( ) {
832+ // The arguments and `self` are parented to the fn.
833+ this. cx . var_parent = this. cx . parent . take ( ) ;
834+ for param in body. params {
835+ this. visit_pat ( param. pat ) ;
836+ }
837+
838+ // The body of the every fn is a root scope.
839+ this. cx . parent = this. cx . var_parent ;
840+ this. visit_expr ( body. value )
841+ } else {
842+ // Only functions have an outer terminating (drop) scope, while
843+ // temporaries in constant initializers may be 'static, but only
844+ // according to rvalue lifetime semantics, using the same
845+ // syntactical rules used for let initializers.
846+ //
847+ // e.g., in `let x = &f();`, the temporary holding the result from
848+ // the `f()` call lives for the entirety of the surrounding block.
849+ //
850+ // Similarly, `const X: ... = &f();` would have the result of `f()`
851+ // live for `'static`, implying (if Drop restrictions on constants
852+ // ever get lifted) that the value *could* have a destructor, but
853+ // it'd get leaked instead of the destructor running during the
854+ // evaluation of `X` (if at all allowed by CTFE).
855+ //
856+ // However, `const Y: ... = g(&f());`, like `let y = g(&f());`,
857+ // would *not* let the `f()` temporary escape into an outer scope
858+ // (i.e., `'static`), which means that after `g` returns, it drops,
859+ // and all the associated destruction scope rules apply.
860+ this. cx . var_parent = None ;
861+ resolve_local ( this, None , Some ( body. value ) ) ;
862+ }
863+ } )
864+ }
859865
860866 fn visit_arm ( & mut self , a : & ' tcx Arm < ' tcx > ) {
861867 resolve_arm ( self , a) ;
0 commit comments