From 6dac78bd55d0b1619c507d71f2c4fdcd3c526ce1 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 19 Jun 2020 20:06:49 -0400 Subject: [PATCH 1/4] Fix -Z unpretty=everybody_loops It turns out that this has not been working for who knows how long. Previously: ``` pub fn h() { 1 + 2; } ``` After this change: ``` pub fn h() { loop {} } ``` This only affected the pass when run with the command line pretty-printing option, so rustdoc was still replacing bodies with `loop {}`. --- src/librustc_driver/lib.rs | 1 + src/librustc_interface/interface.rs | 1 + src/librustc_interface/passes.rs | 3 +++ src/librustc_interface/queries.rs | 1 + src/librustc_session/config.rs | 5 +++-- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ccea041699ee1..b45ab0f80ffac 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -307,6 +307,7 @@ pub fn run_compiler( compiler.output_file().as_ref().map(|p| &**p), ); } + trace!("finished pretty-printing"); return early_exit(); } diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 5aad64f84cee3..920cc6021e687 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -202,6 +202,7 @@ pub fn run_compiler_in_existing_thread_pool( } pub fn run_compiler(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R { + log::trace!("run_compiler"); let stderr = config.stderr.take(); util::spawn_thread_pool( config.opts.edition, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 1ed9bc3f1f509..c0a67f20a1e8c 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -101,6 +101,7 @@ pub fn configure_and_expand( krate: ast::Crate, crate_name: &str, ) -> Result<(ast::Crate, BoxedResolver)> { + log::trace!("configure_and_expand"); // Currently, we ignore the name resolution data structures for the purposes of dependency // tracking. Instead we will run name resolution and include its output in the hash of each // item, much like we do for macro expansion. In other words, the hash reflects not just @@ -230,6 +231,7 @@ fn configure_and_expand_inner<'a>( resolver_arenas: &'a ResolverArenas<'a>, metadata_loader: &'a MetadataLoaderDyn, ) -> Result<(ast::Crate, Resolver<'a>)> { + log::trace!("configure_and_expand_inner"); pre_expansion_lint(sess, lint_store, &krate); let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas); @@ -357,6 +359,7 @@ fn configure_and_expand_inner<'a>( should_loop |= true; } if should_loop { + log::debug!("replacing bodies with loop {{}}"); util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate); } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 283be165c192c..4a41c3e97cafc 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -169,6 +169,7 @@ impl<'tcx> Queries<'tcx> { pub fn expansion( &self, ) -> Result<&Query<(ast::Crate, Steal>>, Lrc)>> { + log::trace!("expansion"); self.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let (krate, lint_store) = self.register_plugins()?.take(); diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 411a6eecbba15..98b0b516667b1 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1826,6 +1826,7 @@ fn parse_pretty( } } }; + log::debug!("got unpretty option: {:?}", first); first } } @@ -1954,9 +1955,9 @@ impl PpMode { use PpMode::*; use PpSourceMode::*; match *self { - PpmSource(PpmNormal | PpmEveryBodyLoops | PpmIdentified) => false, + PpmSource(PpmNormal | PpmIdentified) => false, - PpmSource(PpmExpanded | PpmExpandedIdentified | PpmExpandedHygiene) + PpmSource(PpmExpanded | PpmEveryBodyLoops | PpmExpandedIdentified | PpmExpandedHygiene) | PpmHir(_) | PpmHirTree(_) | PpmMir From fd834eec3a92d5ecd0800d414c14b42cf8078fb5 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 20 Jun 2020 00:27:22 -0400 Subject: [PATCH 2/4] Don't generate fake IDs in ReplaceBodyWithLoop --- src/librustc_interface/util.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 924908e572487..45597f4a8e0a0 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -1,6 +1,6 @@ use log::info; use rustc_ast::ast::{AttrVec, BlockCheckMode}; -use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *}; +use rustc_ast::mut_visit::{/*visit_clobber,*/ MutVisitor, *}; use rustc_ast::ptr::P; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_ast::{self, ast}; @@ -29,7 +29,7 @@ use smallvec::SmallVec; use std::env; use std::io::{self, Write}; use std::mem; -use std::ops::DerefMut; +//use std::ops::DerefMut; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex, Once}; #[cfg(not(parallel_compiler))] @@ -593,7 +593,7 @@ pub fn build_output_filenames( // [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401 pub struct ReplaceBodyWithLoop<'a, 'b> { within_static_or_const: bool, - nested_blocks: Option>, + nested_blocks: Option>, resolver: &'a mut Resolver<'b>, } @@ -707,6 +707,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { } } + /* fn block_to_stmt(b: ast::Block, resolver: &mut Resolver<'_>) -> ast::Stmt { let expr = P(ast::Expr { id: resolver.next_node_id(), @@ -722,6 +723,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { span: rustc_span::DUMMY_SP, } } + */ let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.resolver); let loop_expr = P(ast::Expr { @@ -741,9 +743,9 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { if self.within_static_or_const { noop_visit_block(b, self) } else { - visit_clobber(b.deref_mut(), |b| { + //visit_clobber(b.deref_mut(), |b| { let mut stmts = vec![]; - for s in b.stmts { + for s in b.stmts.drain(..) { let old_blocks = self.nested_blocks.replace(vec![]); stmts.extend(self.flat_map_stmt(s).into_iter().filter(|s| s.is_item())); @@ -751,25 +753,27 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { // we put a Some in there earlier with that replace(), so this is valid let new_blocks = self.nested_blocks.take().unwrap(); self.nested_blocks = old_blocks; - stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, self.resolver))); + stmts.extend(new_blocks); //.into_iter().map(|b| block_to_stmt(b, self.resolver))); } - let mut new_block = ast::Block { stmts, ..b }; + //let mut new_block = ast::Block { stmts, ..b }; if let Some(old_blocks) = self.nested_blocks.as_mut() { //push our fresh block onto the cache and yield an empty block with `loop {}` - if !new_block.stmts.is_empty() { - old_blocks.push(new_block); + if !stmts.is_empty() { + //old_blocks.push(new_block); + old_blocks.extend(stmts); } - stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver) + b.stmts = vec![loop_stmt]; + //stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver) } else { //push `loop {}` onto the end of our fresh block and yield that - new_block.stmts.push(loop_stmt); + stmts.push(loop_stmt); - new_block + b.stmts = stmts; } - }) + //}) } } From e3ab507d97f1c809b3e4cbd05f3137460b77f63b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 20 Jun 2020 00:35:04 -0400 Subject: [PATCH 3/4] Cleanup - x.py fmt - Remove commented-out code - Change variable names to match usage - Fix indentation --- src/librustc_interface/util.rs | 79 ++++++++++++---------------------- src/librustc_session/config.rs | 4 +- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 45597f4a8e0a0..9be66847eeec4 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -1,6 +1,6 @@ use log::info; use rustc_ast::ast::{AttrVec, BlockCheckMode}; -use rustc_ast::mut_visit::{/*visit_clobber,*/ MutVisitor, *}; +use rustc_ast::mut_visit::{MutVisitor, *}; use rustc_ast::ptr::P; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_ast::{self, ast}; @@ -29,7 +29,6 @@ use smallvec::SmallVec; use std::env; use std::io::{self, Write}; use std::mem; -//use std::ops::DerefMut; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex, Once}; #[cfg(not(parallel_compiler))] @@ -593,21 +592,21 @@ pub fn build_output_filenames( // [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401 pub struct ReplaceBodyWithLoop<'a, 'b> { within_static_or_const: bool, - nested_blocks: Option>, + nested_items: Option>, resolver: &'a mut Resolver<'b>, } impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { pub fn new(resolver: &'a mut Resolver<'b>) -> ReplaceBodyWithLoop<'a, 'b> { - ReplaceBodyWithLoop { within_static_or_const: false, nested_blocks: None, resolver } + ReplaceBodyWithLoop { within_static_or_const: false, nested_items: None, resolver } } fn run R>(&mut self, is_const: bool, action: F) -> R { let old_const = mem::replace(&mut self.within_static_or_const, is_const); - let old_blocks = self.nested_blocks.take(); + let old_blocks = self.nested_items.take(); let ret = action(self); self.within_static_or_const = old_const; - self.nested_blocks = old_blocks; + self.nested_items = old_blocks; ret } @@ -694,6 +693,8 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { } fn visit_block(&mut self, b: &mut P) { + // WARNING: this generates a dummy span and so should not be made the parent of any stmt that is not a dummy. + // See https://github.com/rust-lang/rust/issues/71104. fn stmt_to_block( rules: ast::BlockCheckMode, s: Option, @@ -707,24 +708,6 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { } } - /* - fn block_to_stmt(b: ast::Block, resolver: &mut Resolver<'_>) -> ast::Stmt { - let expr = P(ast::Expr { - id: resolver.next_node_id(), - kind: ast::ExprKind::Block(P(b), None), - span: rustc_span::DUMMY_SP, - attrs: AttrVec::new(), - tokens: None, - }); - - ast::Stmt { - id: resolver.next_node_id(), - kind: ast::StmtKind::Expr(expr), - span: rustc_span::DUMMY_SP, - } - } - */ - let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.resolver); let loop_expr = P(ast::Expr { kind: ast::ExprKind::Loop(P(empty_block), None), @@ -741,39 +724,33 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { }; if self.within_static_or_const { - noop_visit_block(b, self) - } else { - //visit_clobber(b.deref_mut(), |b| { - let mut stmts = vec![]; - for s in b.stmts.drain(..) { - let old_blocks = self.nested_blocks.replace(vec![]); + return noop_visit_block(b, self); + } - stmts.extend(self.flat_map_stmt(s).into_iter().filter(|s| s.is_item())); + let mut items = vec![]; + for s in b.stmts.drain(..) { + let old_items = self.nested_items.replace(vec![]); - // we put a Some in there earlier with that replace(), so this is valid - let new_blocks = self.nested_blocks.take().unwrap(); - self.nested_blocks = old_blocks; - stmts.extend(new_blocks); //.into_iter().map(|b| block_to_stmt(b, self.resolver))); - } + items.extend(self.flat_map_stmt(s).into_iter().filter(|s| s.is_item())); - //let mut new_block = ast::Block { stmts, ..b }; + // we put a Some in there earlier with that replace(), so this is valid + let nested_items = self.nested_items.take().unwrap(); + self.nested_items = old_items; + items.extend(nested_items); + } - if let Some(old_blocks) = self.nested_blocks.as_mut() { - //push our fresh block onto the cache and yield an empty block with `loop {}` - if !stmts.is_empty() { - //old_blocks.push(new_block); - old_blocks.extend(stmts); - } + if let Some(nested_items) = self.nested_items.as_mut() { + // add our items to the existing statements and yield an empty block with `loop {}` + if !items.is_empty() { + nested_items.extend(items); + } - b.stmts = vec![loop_stmt]; - //stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver) - } else { - //push `loop {}` onto the end of our fresh block and yield that - stmts.push(loop_stmt); + b.stmts = vec![loop_stmt]; + } else { + // push `loop {}` onto the end of our fresh block and yield that + items.push(loop_stmt); - b.stmts = stmts; - } - //}) + b.stmts = items; } } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 98b0b516667b1..ff94a43c4f1a2 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1957,7 +1957,9 @@ impl PpMode { match *self { PpmSource(PpmNormal | PpmIdentified) => false, - PpmSource(PpmExpanded | PpmEveryBodyLoops | PpmExpandedIdentified | PpmExpandedHygiene) + PpmSource( + PpmExpanded | PpmEveryBodyLoops | PpmExpandedIdentified | PpmExpandedHygiene, + ) | PpmHir(_) | PpmHirTree(_) | PpmMir From ab30797e70477ac6e6cffbba52a95ea9db46cabb Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 7 Jun 2020 15:13:40 -0700 Subject: [PATCH 4/4] Add `rustdoc` tests from #72088 --- src/test/rustdoc/macro-in-async-block.rs | 9 +++++++++ src/test/rustdoc/macro-in-closure.rs | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 src/test/rustdoc/macro-in-async-block.rs diff --git a/src/test/rustdoc/macro-in-async-block.rs b/src/test/rustdoc/macro-in-async-block.rs new file mode 100644 index 0000000000000..b4aaacf7b3d40 --- /dev/null +++ b/src/test/rustdoc/macro-in-async-block.rs @@ -0,0 +1,9 @@ +// Regression issue for rustdoc ICE encountered in PR #72088. +// edition:2018 +#![feature(decl_macro)] + +fn main() { + async { + macro m() {} + }; +} diff --git a/src/test/rustdoc/macro-in-closure.rs b/src/test/rustdoc/macro-in-closure.rs index 298ff601de89f..b4411d927e271 100644 --- a/src/test/rustdoc/macro-in-closure.rs +++ b/src/test/rustdoc/macro-in-closure.rs @@ -6,4 +6,11 @@ fn main() { || { macro m() {} }; + + let _ = || { + macro n() {} + }; + + let cond = true; + let _ = || if cond { macro n() {} } else { panic!() }; }