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. --When I am studying the related in , I found another ICE. Although I haven't figured out the root cause, I suspect they can be fixed together. <!-- 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. --It can be reproduced by nightly and beta versions. : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Assigning as discussed as part of the and removing .
I wonder if this is close enough to and to be considered duplicate
This issue is unrelated to either of those
I don't think this is - it only occurs with a strange input, and then only after errors have already been emitted.
ok thanks I'll downgrade to p-low label +P-low -P-medium
I found a similar ICE using See also
A user in get's ICE with valid code and I think it's the same underlying problem. Should this issue be bumped to ?
All of the ICEs only occur after an error is emitted. However, I'll start working on a fix
any updates? :upsidedownface:

Discussion:
use rustc_ast::NodeId; use rustc_ast::{mut_visit, visit}; use rustc_ast::{Attribute, HasAttrs, HasTokens}; <ins> use rustc_errors::PResult; </ins> use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::config::StripUnconfigured; use rustc_expand::configure;

// the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization // process is lossless, so this process is invisible to proc-macros. <del> let parse_annotatable_with: fn(&mut Parser<'_>) -> _ = match annotatable { Annotatable::Item(_) => { |parser| Annotatable::Item(parser.parse_item(ForceCollect::Yes).unwrap().unwrap()) } Annotatable::TraitItem(_) => |parser| { Annotatable::TraitItem( parser.parse_trait_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), ) }, Annotatable::ImplItem(_) => |parser| { Annotatable::ImplItem( parser.parse_impl_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), ) }, Annotatable::ForeignItem(_) => |parser| { Annotatable::ForeignItem( parser.parse_foreign_item(ForceCollect::Yes).unwrap().unwrap().unwrap(), ) }, Annotatable::Stmt(_) => |parser| { Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes).unwrap().unwrap())) }, Annotatable::Expr(_) => { |parser| Annotatable::Expr(parser.parse_expr_force_collect().unwrap()) } _ => unreachable!(), }; </del> <ins> let parse_annotatable_with: for<'a> fn(&mut Parser<'a>) -> PResult<'a, _> = match annotatable { Annotatable::Item(_) => { |parser| Ok(Annotatable::Item(parser.parse_item(ForceCollect::Yes)?.unwrap())) } Annotatable::TraitItem(_) => |parser| { Ok(Annotatable::TraitItem( parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap(), )) }, Annotatable::ImplItem(_) => |parser| { Ok(Annotatable::ImplItem( parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap(), )) }, Annotatable::ForeignItem(_) => |parser| { Ok(Annotatable::ForeignItem( parser.parse_foreign_item(ForceCollect::Yes)?.unwrap().unwrap(), )) }, Annotatable::Stmt(_) => |parser| { Ok(Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes)?.unwrap()))) }, Annotatable::Expr(_) => { |parser| Ok(Annotatable::Expr(parser.parse_expr_force_collect()?)) } _ => unreachable!(), }; </ins> // 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`) // to `None`-delimited groups containing the corresponding tokens. This

let mut parser = rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None); parser.capture_cfg = true; <del> annotatable = parse_annotatable_with(&mut parser); </del> <ins> match parse_annotatable_with(&mut parser) { Ok(a) => annotatable = a, Err(mut err) => { err.emit(); return Some(annotatable); } } </ins> // Now that we have our re-parsed `AttrTokenStream`, recursively configuring // our attribute target will correctly the tokens as well.

panic!("Unexpected last token {:?}", last_token) } } <del> assert!(stack.is_empty(), "Stack should be empty: final_buf={:?} stack={:?}", final_buf, stack); </del> AttrTokenStream::new(final_buf.inner) }

<ins> macro_rules! values { ($($token:ident($value:literal) $(as $inner:ty)? => $attr:meta,)*) => { #[derive(Debug)] pub enum TokenKind { $( #[$attr] $token $($inner)? = $value, )* } }; } //~^^^^^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `(String)` //~| ERROR macro expansion ignores token `(String)` and any following values!(STRING(1) as (String) => cfg(test),); //~^ ERROR expected one of `!` or `::`, found `<eof>` fn main() {} </ins>

<ins> error: expected one of `(`, `,`, `=`, `{`, or `}`, found `(String)` --> $DIR/syntax-error-recovery.rs:7:26 | LL |                 $token $($inner)? = $value, |                          ^^^^^^ expected one of `(`, `,`, `=`, `{`, or `}` ... LL | values!(STRING(1) as (String) => cfg(test),); | -------------------------------------------- in this macro invocation | = note: this error originates in the macro `values` (in Nightly builds, run with -Z macro-backtrace for more info) error: macro expansion ignores token `(String)` and any following --> $DIR/syntax-error-recovery.rs:7:26 | LL |                 $token $($inner)? = $value, |                          ^^^^^^ ... LL | values!(STRING(1) as (String) => cfg(test),); | -------------------------------------------- caused by the macro expansion here | = note: the usage of `values!` is likely invalid in item context error: expected one of `!` or `::`, found `<eof>` --> $DIR/syntax-error-recovery.rs:15:9 | LL | values!(STRING(1) as (String) => cfg(test),); |         ^^^^^^ expected one of `!` or `::` error: aborting due to 3 previous errors </ins>