Skip to content

Commit f3733a2

Browse files
make everybody_loops keep item declarations
1 parent ed8d14d commit f3733a2

File tree

2 files changed

+71
-24
lines changed

2 files changed

+71
-24
lines changed

src/librustc_driver/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#![feature(box_syntax)]
2222
#![cfg_attr(unix, feature(libc))]
23+
#![feature(option_replace)]
2324
#![feature(quote)]
2425
#![feature(rustc_diagnostic_macros)]
2526
#![feature(slice_sort_by_cached_key)]

src/librustc_driver/pretty.rs

+70-24
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use syntax::fold::{self, Folder};
3333
use syntax::print::{pprust};
3434
use syntax::print::pprust::PrintState;
3535
use syntax::ptr::P;
36+
use syntax::util::ThinVec;
3637
use syntax::util::small_vector::SmallVector;
3738
use syntax_pos::{self, FileName};
3839

@@ -650,12 +651,17 @@ impl UserIdentifiedItem {
650651
// [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401
651652
pub struct ReplaceBodyWithLoop<'a> {
652653
within_static_or_const: bool,
654+
nested_blocks: Option<Vec<ast::Block>>,
653655
sess: &'a Session,
654656
}
655657

656658
impl<'a> ReplaceBodyWithLoop<'a> {
657659
pub fn new(sess: &'a Session) -> ReplaceBodyWithLoop<'a> {
658-
ReplaceBodyWithLoop { within_static_or_const: false, sess }
660+
ReplaceBodyWithLoop {
661+
within_static_or_const: false,
662+
nested_blocks: None,
663+
sess
664+
}
659665
}
660666

661667
fn run<R, F: FnOnce(&mut Self) -> R>(&mut self, is_const: bool, action: F) -> R {
@@ -740,41 +746,81 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> {
740746
}
741747

742748
fn fold_block(&mut self, b: P<ast::Block>) -> P<ast::Block> {
743-
fn expr_to_block(rules: ast::BlockCheckMode,
749+
fn stmt_to_block(rules: ast::BlockCheckMode,
744750
recovered: bool,
745-
e: Option<P<ast::Expr>>,
746-
sess: &Session) -> P<ast::Block> {
747-
P(ast::Block {
748-
stmts: e.map(|e| {
749-
ast::Stmt {
750-
id: sess.next_node_id(),
751-
span: e.span,
752-
node: ast::StmtKind::Expr(e),
753-
}
754-
})
755-
.into_iter()
756-
.collect(),
751+
s: Option<ast::Stmt>,
752+
sess: &Session) -> ast::Block {
753+
ast::Block {
754+
stmts: s.into_iter().collect(),
757755
rules,
758756
id: sess.next_node_id(),
759757
span: syntax_pos::DUMMY_SP,
760758
recovered,
761-
})
759+
}
762760
}
763761

764-
if !self.within_static_or_const {
765-
766-
let empty_block = expr_to_block(BlockCheckMode::Default, false, None, self.sess);
767-
let loop_expr = P(ast::Expr {
768-
node: ast::ExprKind::Loop(empty_block, None),
769-
id: self.sess.next_node_id(),
762+
fn block_to_stmt(b: ast::Block, sess: &Session) -> ast::Stmt {
763+
let expr = P(ast::Expr {
764+
id: sess.next_node_id(),
765+
node: ast::ExprKind::Block(P(b), None),
770766
span: syntax_pos::DUMMY_SP,
771-
attrs: ast::ThinVec::new(),
767+
attrs: ThinVec::new(),
772768
});
773769

774-
expr_to_block(b.rules, b.recovered, Some(loop_expr), self.sess)
770+
ast::Stmt {
771+
id: sess.next_node_id(),
772+
node: ast::StmtKind::Expr(expr),
773+
span: syntax_pos::DUMMY_SP,
774+
}
775+
}
776+
777+
let empty_block = stmt_to_block(BlockCheckMode::Default, false, None, self.sess);
778+
let loop_expr = P(ast::Expr {
779+
node: ast::ExprKind::Loop(P(empty_block), None),
780+
id: self.sess.next_node_id(),
781+
span: syntax_pos::DUMMY_SP,
782+
attrs: ast::ThinVec::new(),
783+
});
784+
785+
let loop_stmt = ast::Stmt {
786+
id: self.sess.next_node_id(),
787+
span: syntax_pos::DUMMY_SP,
788+
node: ast::StmtKind::Expr(loop_expr),
789+
};
775790

776-
} else {
791+
if self.within_static_or_const {
777792
fold::noop_fold_block(b, self)
793+
} else {
794+
b.map(|b| {
795+
let old_blocks = self.nested_blocks.replace(vec![]);
796+
797+
let mut stmts = b.stmts.into_iter()
798+
.flat_map(|s| self.fold_stmt(s))
799+
.filter(|s| s.is_item())
800+
.collect::<Vec<ast::Stmt>>();
801+
802+
// we put a Some in there earlier with that replace(), so this is valid
803+
let new_blocks = self.nested_blocks.take().unwrap();
804+
self.nested_blocks = old_blocks;
805+
stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, &self.sess)));
806+
807+
let mut new_block = ast::Block {
808+
stmts,
809+
..b
810+
};
811+
812+
if let Some(old_blocks) = self.nested_blocks.as_mut() {
813+
//push our fresh block onto the cache and yield an empty block with `loop {}`
814+
old_blocks.push(new_block);
815+
816+
stmt_to_block(b.rules, b.recovered, Some(loop_stmt), self.sess)
817+
} else {
818+
//push `loop {}` onto the end of our fresh block and yield that
819+
new_block.stmts.push(loop_stmt);
820+
821+
new_block
822+
}
823+
})
778824
}
779825
}
780826

0 commit comments

Comments
 (0)