@@ -80,6 +80,8 @@ macro_rules! make_mir_visitor {
8080 self . super_body( body) ;
8181 }
8282
83+ extra_body_methods!( $( $mutability) ?) ;
84+
8385 fn visit_basic_block_data(
8486 & mut self ,
8587 block: BasicBlock ,
@@ -287,63 +289,7 @@ macro_rules! make_mir_visitor {
287289 & mut self ,
288290 body: & $( $mutability) ? Body <' tcx>,
289291 ) {
290- let span = body. span;
291- if let Some ( gen ) = & $( $mutability) ? body. generator {
292- if let Some ( yield_ty) = $( & $mutability) ? gen . yield_ty {
293- self . visit_ty(
294- yield_ty,
295- TyContext :: YieldTy ( SourceInfo :: outermost( span) )
296- ) ;
297- }
298- }
299-
300- // for best performance, we want to use an iterator rather
301- // than a for-loop, to avoid calling `body::Body::invalidate` for
302- // each basic block.
303- #[ allow( unused_macro_rules) ]
304- macro_rules! basic_blocks {
305- ( mut ) => ( body. basic_blocks_mut( ) . iter_enumerated_mut( ) ) ;
306- ( ) => ( body. basic_blocks( ) . iter_enumerated( ) ) ;
307- }
308- for ( bb, data) in basic_blocks!( $( $mutability) ?) {
309- self . visit_basic_block_data( bb, data) ;
310- }
311-
312- for scope in & $( $mutability) ? body. source_scopes {
313- self . visit_source_scope_data( scope) ;
314- }
315-
316- self . visit_ty(
317- $( & $mutability) ? body. return_ty( ) ,
318- TyContext :: ReturnTy ( SourceInfo :: outermost( body. span) )
319- ) ;
320-
321- for local in body. local_decls. indices( ) {
322- self . visit_local_decl( local, & $( $mutability) ? body. local_decls[ local] ) ;
323- }
324-
325- #[ allow( unused_macro_rules) ]
326- macro_rules! type_annotations {
327- ( mut ) => ( body. user_type_annotations. iter_enumerated_mut( ) ) ;
328- ( ) => ( body. user_type_annotations. iter_enumerated( ) ) ;
329- }
330-
331- for ( index, annotation) in type_annotations!( $( $mutability) ?) {
332- self . visit_user_type_annotation(
333- index, annotation
334- ) ;
335- }
336-
337- for var_debug_info in & $( $mutability) ? body. var_debug_info {
338- self . visit_var_debug_info( var_debug_info) ;
339- }
340-
341- self . visit_span( $( & $mutability) ? body. span) ;
342-
343- for const_ in & $( $mutability) ? body. required_consts {
344- let location = START_BLOCK . start_location( ) ;
345- self . visit_constant( const_, location) ;
346- }
292+ super_body!( self , body, $( $mutability, true ) ?) ;
347293 }
348294
349295 fn super_basic_block_data( & mut self ,
@@ -982,12 +928,7 @@ macro_rules! make_mir_visitor {
982928 body: & $( $mutability) ? Body <' tcx>,
983929 location: Location
984930 ) {
985- #[ allow( unused_macro_rules) ]
986- macro_rules! basic_blocks {
987- ( mut ) => ( body. basic_blocks_mut( ) ) ;
988- ( ) => ( body. basic_blocks( ) ) ;
989- }
990- let basic_block = & $( $mutability) ? basic_blocks!( $( $mutability) ?) [ location. block] ;
931+ let basic_block = & $( $mutability) ? basic_blocks!( body, $( $mutability, true ) ?) [ location. block] ;
991932 if basic_block. statements. len( ) == location. statement_index {
992933 if let Some ( ref $( $mutability) ? terminator) = basic_block. terminator {
993934 self . visit_terminator( terminator, location)
@@ -1002,6 +943,94 @@ macro_rules! make_mir_visitor {
1002943 }
1003944}
1004945
946+ macro_rules! basic_blocks {
947+ ( $body: ident, mut , true ) => {
948+ $body. basic_blocks. as_mut( )
949+ } ;
950+ ( $body: ident, mut , false ) => {
951+ $body. basic_blocks. as_mut_preserves_cfg( )
952+ } ;
953+ ( $body: ident, ) => {
954+ $body. basic_blocks( )
955+ } ;
956+ }
957+
958+ macro_rules! basic_blocks_iter {
959+ ( $body: ident, mut , $invalidate: tt) => {
960+ basic_blocks!( $body, mut , $invalidate) . iter_enumerated_mut( )
961+ } ;
962+ ( $body: ident, ) => {
963+ basic_blocks!( $body, ) . iter_enumerated( )
964+ } ;
965+ }
966+
967+ macro_rules! extra_body_methods {
968+ ( mut ) => {
969+ fn visit_body_preserves_cfg( & mut self , body: & mut Body <' tcx>) {
970+ self . super_body_preserves_cfg( body) ;
971+ }
972+
973+ fn super_body_preserves_cfg( & mut self , body: & mut Body <' tcx>) {
974+ super_body!( self , body, mut , false ) ;
975+ }
976+ } ;
977+ ( ) => { } ;
978+ }
979+
980+ macro_rules! super_body {
981+ ( $self: ident, $body: ident, $( $mutability: ident, $invalidate: tt) ?) => {
982+ let span = $body. span;
983+ if let Some ( gen ) = & $( $mutability) ? $body. generator {
984+ if let Some ( yield_ty) = $( & $mutability) ? gen . yield_ty {
985+ $self. visit_ty(
986+ yield_ty,
987+ TyContext :: YieldTy ( SourceInfo :: outermost( span) )
988+ ) ;
989+ }
990+ }
991+
992+ for ( bb, data) in basic_blocks_iter!( $body, $( $mutability, $invalidate) ?) {
993+ $self. visit_basic_block_data( bb, data) ;
994+ }
995+
996+ for scope in & $( $mutability) ? $body. source_scopes {
997+ $self. visit_source_scope_data( scope) ;
998+ }
999+
1000+ $self. visit_ty(
1001+ $( & $mutability) ? $body. return_ty( ) ,
1002+ TyContext :: ReturnTy ( SourceInfo :: outermost( $body. span) )
1003+ ) ;
1004+
1005+ for local in $body. local_decls. indices( ) {
1006+ $self. visit_local_decl( local, & $( $mutability) ? $body. local_decls[ local] ) ;
1007+ }
1008+
1009+ #[ allow( unused_macro_rules) ]
1010+ macro_rules! type_annotations {
1011+ ( mut ) => ( $body. user_type_annotations. iter_enumerated_mut( ) ) ;
1012+ ( ) => ( $body. user_type_annotations. iter_enumerated( ) ) ;
1013+ }
1014+
1015+ for ( index, annotation) in type_annotations!( $( $mutability) ?) {
1016+ $self. visit_user_type_annotation(
1017+ index, annotation
1018+ ) ;
1019+ }
1020+
1021+ for var_debug_info in & $( $mutability) ? $body. var_debug_info {
1022+ $self. visit_var_debug_info( var_debug_info) ;
1023+ }
1024+
1025+ $self. visit_span( $( & $mutability) ? $body. span) ;
1026+
1027+ for const_ in & $( $mutability) ? $body. required_consts {
1028+ let location = START_BLOCK . start_location( ) ;
1029+ $self. visit_constant( const_, location) ;
1030+ }
1031+ }
1032+ }
1033+
10051034macro_rules! visit_place_fns {
10061035 ( mut ) => {
10071036 fn tcx<' a>( & ' a self ) -> TyCtxt <' tcx>;
0 commit comments