1
1
use log:: info;
2
2
use rustc_ast:: ast:: { AttrVec , BlockCheckMode } ;
3
- use rustc_ast:: mut_visit:: { /*visit_clobber,*/ MutVisitor , * } ;
3
+ use rustc_ast:: mut_visit:: { MutVisitor , * } ;
4
4
use rustc_ast:: ptr:: P ;
5
5
use rustc_ast:: util:: lev_distance:: find_best_match_for_name;
6
6
use rustc_ast:: { self , ast} ;
@@ -29,7 +29,6 @@ use smallvec::SmallVec;
29
29
use std:: env;
30
30
use std:: io:: { self , Write } ;
31
31
use std:: mem;
32
- //use std::ops::DerefMut;
33
32
use std:: path:: { Path , PathBuf } ;
34
33
use std:: sync:: { Arc , Mutex , Once } ;
35
34
#[ cfg( not( parallel_compiler) ) ]
@@ -593,21 +592,21 @@ pub fn build_output_filenames(
593
592
// [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401
594
593
pub struct ReplaceBodyWithLoop < ' a , ' b > {
595
594
within_static_or_const : bool ,
596
- nested_blocks : Option < Vec < ast:: Stmt > > ,
595
+ nested_items : Option < Vec < ast:: Stmt > > ,
597
596
resolver : & ' a mut Resolver < ' b > ,
598
597
}
599
598
600
599
impl < ' a , ' b > ReplaceBodyWithLoop < ' a , ' b > {
601
600
pub fn new ( resolver : & ' a mut Resolver < ' b > ) -> ReplaceBodyWithLoop < ' a , ' b > {
602
- ReplaceBodyWithLoop { within_static_or_const : false , nested_blocks : None , resolver }
601
+ ReplaceBodyWithLoop { within_static_or_const : false , nested_items : None , resolver }
603
602
}
604
603
605
604
fn run < R , F : FnOnce ( & mut Self ) -> R > ( & mut self , is_const : bool , action : F ) -> R {
606
605
let old_const = mem:: replace ( & mut self . within_static_or_const , is_const) ;
607
- let old_blocks = self . nested_blocks . take ( ) ;
606
+ let old_blocks = self . nested_items . take ( ) ;
608
607
let ret = action ( self ) ;
609
608
self . within_static_or_const = old_const;
610
- self . nested_blocks = old_blocks;
609
+ self . nested_items = old_blocks;
611
610
ret
612
611
}
613
612
@@ -694,6 +693,8 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
694
693
}
695
694
696
695
fn visit_block ( & mut self , b : & mut P < ast:: Block > ) {
696
+ // WARNING: this generates a dummy span and so should not be made the parent of any stmt that is not a dummy.
697
+ // See https://github.com/rust-lang/rust/issues/71104.
697
698
fn stmt_to_block (
698
699
rules : ast:: BlockCheckMode ,
699
700
s : Option < ast:: Stmt > ,
@@ -707,24 +708,6 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
707
708
}
708
709
}
709
710
710
- /*
711
- fn block_to_stmt(b: ast::Block, resolver: &mut Resolver<'_>) -> ast::Stmt {
712
- let expr = P(ast::Expr {
713
- id: resolver.next_node_id(),
714
- kind: ast::ExprKind::Block(P(b), None),
715
- span: rustc_span::DUMMY_SP,
716
- attrs: AttrVec::new(),
717
- tokens: None,
718
- });
719
-
720
- ast::Stmt {
721
- id: resolver.next_node_id(),
722
- kind: ast::StmtKind::Expr(expr),
723
- span: rustc_span::DUMMY_SP,
724
- }
725
- }
726
- */
727
-
728
711
let empty_block = stmt_to_block ( BlockCheckMode :: Default , None , self . resolver ) ;
729
712
let loop_expr = P ( ast:: Expr {
730
713
kind : ast:: ExprKind :: Loop ( P ( empty_block) , None ) ,
@@ -741,39 +724,33 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
741
724
} ;
742
725
743
726
if self . within_static_or_const {
744
- noop_visit_block ( b, self )
745
- } else {
746
- //visit_clobber(b.deref_mut(), |b| {
747
- let mut stmts = vec ! [ ] ;
748
- for s in b. stmts . drain ( ..) {
749
- let old_blocks = self . nested_blocks . replace ( vec ! [ ] ) ;
727
+ return noop_visit_block ( b, self ) ;
728
+ }
750
729
751
- stmts. extend ( self . flat_map_stmt ( s) . into_iter ( ) . filter ( |s| s. is_item ( ) ) ) ;
730
+ let mut items = vec ! [ ] ;
731
+ for s in b. stmts . drain ( ..) {
732
+ let old_items = self . nested_items . replace ( vec ! [ ] ) ;
752
733
753
- // we put a Some in there earlier with that replace(), so this is valid
754
- let new_blocks = self . nested_blocks . take ( ) . unwrap ( ) ;
755
- self . nested_blocks = old_blocks;
756
- stmts. extend ( new_blocks) ; //.into_iter().map(|b| block_to_stmt(b, self.resolver)));
757
- }
734
+ items. extend ( self . flat_map_stmt ( s) . into_iter ( ) . filter ( |s| s. is_item ( ) ) ) ;
758
735
759
- //let mut new_block = ast::Block { stmts, ..b };
736
+ // we put a Some in there earlier with that replace(), so this is valid
737
+ let nested_items = self . nested_items . take ( ) . unwrap ( ) ;
738
+ self . nested_items = old_items;
739
+ items. extend ( nested_items) ;
740
+ }
760
741
761
- if let Some ( old_blocks) = self . nested_blocks . as_mut ( ) {
762
- //push our fresh block onto the cache and yield an empty block with `loop {}`
763
- if !stmts. is_empty ( ) {
764
- //old_blocks.push(new_block);
765
- old_blocks. extend ( stmts) ;
766
- }
742
+ if let Some ( nested_items) = self . nested_items . as_mut ( ) {
743
+ // add our items to the existing statements and yield an empty block with `loop {}`
744
+ if !items. is_empty ( ) {
745
+ nested_items. extend ( items) ;
746
+ }
767
747
768
- b. stmts = vec ! [ loop_stmt] ;
769
- //stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver)
770
- } else {
771
- //push `loop {}` onto the end of our fresh block and yield that
772
- stmts. push ( loop_stmt) ;
748
+ b. stmts = vec ! [ loop_stmt] ;
749
+ } else {
750
+ // push `loop {}` onto the end of our fresh block and yield that
751
+ items. push ( loop_stmt) ;
773
752
774
- b. stmts = stmts;
775
- }
776
- //})
753
+ b. stmts = items;
777
754
}
778
755
}
779
756
0 commit comments