Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --Context: "regression" caught by future-proofing CI from After working on reducing the code, I've identified the root cause of the ICE. For context: this patterns stem from "old" Rust code wanting to support proc-macros emitting item definitions in "statement" position for Rust: the trick is to use the to wrap an item-defs-emitting proc-macro call inside a function so that Rust doesn't interpret it as a statement, refusing the then-unstable stmt-emitting proc-macro call (). <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Bonus: the ICE seems to have been introduced in between today's () and yesterday's nightly. <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</detailscc I suspect this is up your alley
searched nightlies: from nightly-2021-08-01 to nightly-2021-08-10 regressed nightly: nightly-2021-08-07 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-high +A-macros
Thanks nice job

Discussion:
self.cx.force_mode = orig_force_mode; // Finally incorporate all the expanded macros into the input AST fragment. <del> let mut placeholder_expander = PlaceholderExpander::default(); </del> <ins> let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic); </ins> while let Some(expanded_fragments) = expanded_fragments.pop() { for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() { placeholder_expander

} } <ins> // The placeholder expander gives ids to statements, so we avoid folding the id here. </ins> // We don't use `assign_id!` - it will be called when we visit statement's contents // (e.g. an expression, item, or local) <del> let res = noop_flat_map_stmt(stmt, self); </del> <ins> let ast::Stmt { id, kind, span } = stmt; let res = noop_flat_map_stmt_kind(kind, self) .into_iter() .map(|kind| ast::Stmt { id, kind, span }) .collect(); </ins> self.cx.current_expansion.is_trailing_mac = false; res

#![feature(proc_macro_internals)] #![feature(proc_macro_span)] #![feature(try_blocks)] <del> #![recursion_limit = "256"] </del> #[macro_use] extern crate rustc_macros;

<ins> use crate::base::ExtCtxt; </ins> use crate::expand::{AstFragment, AstFragmentKind}; use rustc_ast as ast;

} } <del> #[derive(Default)] pub struct PlaceholderExpander { </del> <ins> pub struct PlaceholderExpander<'a, 'b> { </ins> expanded_fragments: FxHashMap<ast::NodeId, AstFragment>, <ins> cx: &'a mut ExtCtxt<'b>, monotonic: bool, </ins> } <del> impl PlaceholderExpander { </del> <ins> impl<'a, 'b> PlaceholderExpander<'a, 'b> { pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self { PlaceholderExpander { cx, expanded_fragments: FxHashMap::default(), monotonic } } </ins> pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) { fragment.mut_visit_with(self); self.expanded_fragments.insert(id, fragment);

} } <del> impl MutVisitor for PlaceholderExpander { </del> <ins> impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { </ins> fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { if arm.is_placeholder { self.remove(arm.id).make_arms()

_ => noop_visit_ty(ty, self), } } <ins> fn visit_block(&mut self, block: &mut P<ast::Block>) { noop_visit_block(block, self); for stmt in block.stmts.iter_mut() { if self.monotonic { assert_eq!(stmt.id, ast::DUMMY_NODE_ID); stmt.id = self.cx.resolver.next_node_id(); } } } </ins> }