@@ -96,6 +96,30 @@ impl<'a> ParserAnyMacro<'a> {
9696 ensure_complete_parse ( parser, & path, kind. name ( ) , site_span) ;
9797 fragment
9898 }
99+
100+ #[ instrument( skip( cx, tts) ) ]
101+ pub ( crate ) fn from_tts < ' cx > (
102+ cx : & ' cx mut ExtCtxt < ' a > ,
103+ tts : TokenStream ,
104+ site_span : Span ,
105+ arm_span : Span ,
106+ is_local : bool ,
107+ macro_ident : Ident ,
108+ ) -> Self {
109+ Self {
110+ parser : Parser :: new ( & cx. sess . psess , tts, None ) ,
111+
112+ // Pass along the original expansion site and the name of the macro
113+ // so we can print a useful error message if the parse of the expanded
114+ // macro leaves unparsed tokens.
115+ site_span,
116+ macro_ident,
117+ lint_node_id : cx. current_expansion . lint_node_id ,
118+ is_trailing_mac : cx. current_expansion . is_trailing_mac ,
119+ arm_span,
120+ is_local,
121+ }
122+ }
99123}
100124
101125pub ( super ) struct MacroRule {
@@ -207,9 +231,6 @@ fn expand_macro<'cx>(
207231 rules : & [ MacroRule ] ,
208232) -> Box < dyn MacResult + ' cx > {
209233 let psess = & cx. sess . psess ;
210- // Macros defined in the current crate have a real node id,
211- // whereas macros from an external crate have a dummy id.
212- let is_local = node_id != DUMMY_NODE_ID ;
213234
214235 if cx. trace_macros ( ) {
215236 let msg = format ! ( "expanding `{}! {{ {} }}`" , name, pprust:: tts_to_string( & arg) ) ;
@@ -220,7 +241,7 @@ fn expand_macro<'cx>(
220241 let try_success_result = try_match_macro ( psess, name, & arg, rules, & mut NoopTracker ) ;
221242
222243 match try_success_result {
223- Ok ( ( i , rule, named_matches) ) => {
244+ Ok ( ( rule_index , rule, named_matches) ) => {
224245 let mbe:: TokenTree :: Delimited ( rhs_span, _, ref rhs) = rule. rhs else {
225246 cx. dcx ( ) . span_bug ( sp, "malformed macro rhs" ) ;
226247 } ;
@@ -241,27 +262,13 @@ fn expand_macro<'cx>(
241262 trace_macros_note ( & mut cx. expansions , sp, msg) ;
242263 }
243264
244- let p = Parser :: new ( psess, tts, None ) ;
245-
265+ let is_local = is_defined_in_current_crate ( node_id) ;
246266 if is_local {
247- cx. resolver . record_macro_rule_usage ( node_id, i ) ;
267+ cx. resolver . record_macro_rule_usage ( node_id, rule_index ) ;
248268 }
249269
250- // Let the context choose how to interpret the result.
251- // Weird, but useful for X-macros.
252- Box :: new ( ParserAnyMacro {
253- parser : p,
254-
255- // Pass along the original expansion site and the name of the macro
256- // so we can print a useful error message if the parse of the expanded
257- // macro leaves unparsed tokens.
258- site_span : sp,
259- macro_ident : name,
260- lint_node_id : cx. current_expansion . lint_node_id ,
261- is_trailing_mac : cx. current_expansion . is_trailing_mac ,
262- arm_span,
263- is_local,
264- } )
270+ // Let the context choose how to interpret the result. Weird, but useful for X-macros.
271+ Box :: new ( ParserAnyMacro :: from_tts ( cx, tts, sp, arm_span, is_local, name) )
265272 }
266273 Err ( CanRetry :: No ( guar) ) => {
267274 debug ! ( "Will not retry matching as an error was emitted already" ) ;
@@ -373,9 +380,9 @@ pub fn compile_declarative_macro(
373380 node_id : NodeId ,
374381 edition : Edition ,
375382) -> ( SyntaxExtension , usize ) {
376- let is_local = node_id != DUMMY_NODE_ID ;
377383 let mk_syn_ext = |expander| {
378384 let kind = SyntaxExtensionKind :: LegacyBang ( expander) ;
385+ let is_local = is_defined_in_current_crate ( node_id) ;
379386 SyntaxExtension :: new ( sess, kind, span, Vec :: new ( ) , edition, ident. name , attrs, is_local)
380387 } ;
381388 let dummy_syn_ext = |guar| ( mk_syn_ext ( Arc :: new ( DummyExpander ( guar) ) ) , 0 ) ;
@@ -439,7 +446,7 @@ pub fn compile_declarative_macro(
439446 }
440447
441448 // Return the number of rules for unused rule linting, if this is a local macro.
442- let nrules = if is_local { rules. len ( ) } else { 0 } ;
449+ let nrules = if is_defined_in_current_crate ( node_id ) { rules. len ( ) } else { 0 } ;
443450
444451 let expander =
445452 Arc :: new ( MacroRulesMacroExpander { name : ident, span, node_id, transparency, rules } ) ;
@@ -1034,9 +1041,7 @@ fn check_matcher_core<'tt>(
10341041 // definition of this macro_rules, not while (re)parsing
10351042 // the macro when compiling another crate that is using the
10361043 // macro. (See #86567.)
1037- // Macros defined in the current crate have a real node id,
1038- // whereas macros from an external crate have a dummy id.
1039- if node_id != DUMMY_NODE_ID
1044+ if is_defined_in_current_crate ( node_id)
10401045 && matches ! ( kind, NonterminalKind :: Pat ( PatParam { inferred: true } ) )
10411046 && matches ! (
10421047 next_token,
@@ -1296,6 +1301,12 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
12961301 }
12971302}
12981303
1304+ fn is_defined_in_current_crate ( node_id : NodeId ) -> bool {
1305+ // Macros defined in the current crate have a real node id,
1306+ // whereas macros from an external crate have a dummy id.
1307+ node_id != DUMMY_NODE_ID
1308+ }
1309+
12991310pub ( super ) fn parser_from_cx (
13001311 psess : & ParseSess ,
13011312 mut tts : TokenStream ,
0 commit comments