Change:
Steps to reproduce: Extract the archive Run Run The following generated macro is a likely source of error: However, directly putting this macro does not seem to cause a compiler crash: It appears that the crash only occurs when the macro-by-example generated from a proc-macro. The full error message: Using gives a similar result: You can try removing the first one or two parts in the macro pattern and the error disappears.
cc
cc
The offending code is here: TBH, I'm not really sure what it is checking, and I don't have time to look into it right now (work is busy)... Sorry about that. It seems that the procmacro is somehow generating some tokens or TokenTrees (especially in a [i.e. a token repetition]) that don't have spans somehow. is that even possible? It looks like pnkfelix wrote this code originally 4 years ago. It hasn't been touched in years. do you know if there have been any changes in proc_macros that could have exposed this behavior?

Discussion:
return first; } TokenTree::Sequence(sp, ref seq_rep) => { <del> match self.first.get(&sp.entire()) { Some(&Some(ref subfirst)) => { // If the sequence contents can be empty, then the first // token could be the separator token itself. if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { first.add_one_maybe(TokenTree::Token(sep.clone())); } assert!(first.maybe_empty); first.add_all(subfirst); if subfirst.maybe_empty || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne { // continue scanning for more first // tokens, but also make sure we // restore empty-tracking state first.maybe_empty = true; continue; } else { return first; } } </del> <ins> let subfirst_owned; let subfirst = match self.first.get(&sp.entire()) { Some(&Some(ref subfirst)) => subfirst, </ins> Some(&None) => { <del> panic!("assume all sequences have (unique) spans for now"); </del> <ins> subfirst_owned = self.first(&seq_rep.tts[..]); &subfirst_owned </ins> } None => { panic!("We missed a sequence during FirstSets construction"); } <ins> }; // If the sequence contents can be empty, then the first // token could be the separator token itself. if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { first.add_one_maybe(TokenTree::Token(sep.clone())); } assert!(first.maybe_empty); first.add_all(subfirst); if subfirst.maybe_empty || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne { // Continue scanning for more first // tokens, but also make sure we // restore empty-tracking state. first.maybe_empty = true; continue; } else { return first; </ins> } } }

<ins> // force-host // no-prefer-dynamic #![crate_type = "proc-macro"] #![feature(proc_macro_span, proc_macro_hygiene, proc_macro_quote)] extern crate proc_macro; use proc_macro::{quote, Span, TokenStream}; fn assert_same_span(a: Span, b: Span) { assert_eq!(a.start(), b.start()); assert_eq!(a.end(), b.end()); } // This macro generates a macro with the same macro definition as `manual_foo` in // `same-sequence-span.rs` but with the same span for all sequences. #[proc_macro] pub fn make_foo(_: TokenStream) -> TokenStream { let result = quote! { macro_rules! generated_foo { (1 $$x:expr $$($$y:tt,)* $$(= $$z:tt)*) => {}; } }; // Check that all spans are equal. let mut span = None; for tt in result.clone() { match span { None => span = Some(tt.span()), Some(span) => assert_same_span(tt.span(), span), } } result } </ins>

<ins> // aux-build:proc_macro_sequence.rs // Regression test for issue #62831: Check that multiple sequences with the same span in the // left-hand side of a macro definition behave as if they had unique spans, and in particular that // they don't crash the compiler. #![feature(proc_macro_hygiene)] #![allow(unused_macros)] extern crate proc_macro_sequence; // When ignoring spans, this macro has the same macro definition as `generated_foo` in // `proc_macro_sequence.rs`. macro_rules! manual_foo { (1 $x:expr $($y:tt,)*   //~ERROR `$x:expr` may be followed by `$y:tt` $(= $z:tt)*  //~ERROR `$x:expr` may be followed by `=` ) => {}; } proc_macro_sequence::make_foo!(); //~ERROR `$x:expr` may be followed by `$y:tt` //~^ERROR `$x:expr` may be followed by `=` fn main() {} </ins>

<ins> error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:15:18 | LL |     (1 $x:expr $($y:tt,)* |                  ^^^^^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:16:18 | LL |                $(= $z:tt)* |                  ^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:20:1 | LL | proc_macro_sequence::make_foo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:20:1 | LL | proc_macro_sequence::make_foo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments | = note: allowed there are: `=>`, `,` or `;` error: aborting due to 4 previous errors </ins>