@@ -782,25 +782,8 @@ impl<'tcx> RegionResolutionVisitor<'tcx> {
782
782
}
783
783
self . enter_scope ( Scope { id, data : ScopeData :: Node } ) ;
784
784
}
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
- ) ;
803
785
786
+ fn enter_body ( & mut self , hir_id : hir:: HirId , f : impl FnOnce ( & mut Self ) ) {
804
787
// Save all state that is specific to the outer function
805
788
// body. These will be restored once down below, once we've
806
789
// visited the body.
@@ -812,50 +795,73 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
812
795
// control flow assumptions. This doesn't apply to nested
813
796
// bodies within the `+=` statements. See #69307.
814
797
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 ) ;
819
799
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 } ) ;
825
802
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 ) ;
852
804
853
805
// Restore context we had at the start.
854
806
self . expr_and_pat_count = outer_ec;
855
807
self . cx = outer_cx;
856
808
self . terminating_scopes = outer_ts;
857
809
self . pessimistic_yield = outer_pessimistic_yield;
858
810
}
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
+ }
859
865
860
866
fn visit_arm ( & mut self , a : & ' tcx Arm < ' tcx > ) {
861
867
resolve_arm ( self , a) ;
0 commit comments