@@ -183,6 +183,47 @@ impl<'matcher> Tracker<'matcher> for NoopTracker {
183183 }
184184}
185185
186+ #[ instrument( skip( cx, tts) ) ]
187+ pub fn expand_token_stream < ' cx > (
188+ cx : & ' cx mut ExtCtxt < ' _ > ,
189+ sp : Span ,
190+ arm_span : Span ,
191+ node_id : NodeId ,
192+ name : Ident ,
193+ rule_index : usize ,
194+ tts : TokenStream ,
195+ ) -> Box < dyn MacResult + ' cx > {
196+ let psess = & cx. sess . psess ;
197+ // Macros defined in the current crate have a real node id,
198+ // whereas macros from an external crate have a dummy id.
199+ let is_local = node_id != DUMMY_NODE_ID ;
200+
201+ if cx. trace_macros ( ) {
202+ let msg = format ! ( "to `{}`" , pprust:: tts_to_string( & tts) ) ;
203+ trace_macros_note ( & mut cx. expansions , sp, msg) ;
204+ }
205+
206+ let p = Parser :: new ( psess, tts, None ) ;
207+
208+ if is_local {
209+ cx. resolver . record_macro_rule_usage ( node_id, rule_index) ;
210+ }
211+
212+ Box :: new ( ParserAnyMacro {
213+ parser : p,
214+
215+ // Pass along the original expansion site and the name of the macro
216+ // so we can print a useful error message if the parse of the expanded
217+ // macro leaves unparsed tokens.
218+ site_span : sp,
219+ macro_ident : name,
220+ lint_node_id : cx. current_expansion . lint_node_id ,
221+ is_trailing_mac : cx. current_expansion . is_trailing_mac ,
222+ arm_span,
223+ is_local,
224+ } )
225+ }
226+
186227/// Expands the rules based macro defined by `lhses` and `rhses` for a given
187228/// input `arg`.
188229#[ instrument( skip( cx, transparency, arg, lhses, rhses) ) ]
@@ -198,9 +239,6 @@ fn expand_macro<'cx>(
198239 rhses : & [ mbe:: TokenTree ] ,
199240) -> Box < dyn MacResult + ' cx > {
200241 let psess = & cx. sess . psess ;
201- // Macros defined in the current crate have a real node id,
202- // whereas macros from an external crate have a dummy id.
203- let is_local = node_id != DUMMY_NODE_ID ;
204242
205243 if cx. trace_macros ( ) {
206244 let msg = format ! ( "expanding `{}! {{ {} }}`" , name, pprust:: tts_to_string( & arg) ) ;
@@ -211,12 +249,12 @@ fn expand_macro<'cx>(
211249 let try_success_result = try_match_macro ( psess, name, & arg, lhses, & mut NoopTracker ) ;
212250
213251 match try_success_result {
214- Ok ( ( i , named_matches) ) => {
215- let ( rhs, rhs_span) : ( & mbe:: Delimited , DelimSpan ) = match & rhses[ i ] {
252+ Ok ( ( rule_index , named_matches) ) => {
253+ let ( rhs, rhs_span) : ( & mbe:: Delimited , DelimSpan ) = match & rhses[ rule_index ] {
216254 mbe:: TokenTree :: Delimited ( span, _, delimited) => ( & delimited, * span) ,
217255 _ => cx. dcx ( ) . span_bug ( sp, "malformed macro rhs" ) ,
218256 } ;
219- let arm_span = rhses[ i ] . span ( ) ;
257+ let arm_span = rhses[ rule_index ] . span ( ) ;
220258
221259 // rhs has holes ( `$id` and `$(...)` that need filled)
222260 let id = cx. current_expansion . id ;
@@ -228,32 +266,9 @@ fn expand_macro<'cx>(
228266 }
229267 } ;
230268
231- if cx. trace_macros ( ) {
232- let msg = format ! ( "to `{}`" , pprust:: tts_to_string( & tts) ) ;
233- trace_macros_note ( & mut cx. expansions , sp, msg) ;
234- }
235-
236- let p = Parser :: new ( psess, tts, None ) ;
237-
238- if is_local {
239- cx. resolver . record_macro_rule_usage ( node_id, i) ;
240- }
241-
242269 // Let the context choose how to interpret the result.
243270 // Weird, but useful for X-macros.
244- Box :: new ( ParserAnyMacro {
245- parser : p,
246-
247- // Pass along the original expansion site and the name of the macro
248- // so we can print a useful error message if the parse of the expanded
249- // macro leaves unparsed tokens.
250- site_span : sp,
251- macro_ident : name,
252- lint_node_id : cx. current_expansion . lint_node_id ,
253- is_trailing_mac : cx. current_expansion . is_trailing_mac ,
254- arm_span,
255- is_local,
256- } )
271+ expand_token_stream ( cx, sp, arm_span, node_id, name, rule_index, tts)
257272 }
258273 Err ( CanRetry :: No ( guar) ) => {
259274 debug ! ( "Will not retry matching as an error was emitted already" ) ;
0 commit comments