@@ -156,6 +156,7 @@ impl<'a> ParserAnyMacro<'a> {
156
156
}
157
157
158
158
struct MacroRulesMacroExpander {
159
+ id : NodeId ,
159
160
name : Ident ,
160
161
span : Span ,
161
162
transparency : Transparency ,
@@ -179,6 +180,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
179
180
cx,
180
181
sp,
181
182
self . span ,
183
+ self . id ,
182
184
self . name ,
183
185
self . transparency ,
184
186
input,
@@ -207,6 +209,7 @@ fn generic_extension<'cx, 'tt>(
207
209
cx : & ' cx mut ExtCtxt < ' _ > ,
208
210
sp : Span ,
209
211
def_span : Span ,
212
+ id : NodeId ,
210
213
name : Ident ,
211
214
transparency : Transparency ,
212
215
arg : TokenStream ,
@@ -297,6 +300,8 @@ fn generic_extension<'cx, 'tt>(
297
300
let mut p = Parser :: new ( sess, tts, false , None ) ;
298
301
p. last_type_ascription = cx. current_expansion . prior_type_ascription ;
299
302
303
+ cx. resolver . record_macro_rule_usage ( id, i) ;
304
+
300
305
// Let the context choose how to interpret the result.
301
306
// Weird, but useful for X-macros.
302
307
return Box :: new ( ParserAnyMacro {
@@ -375,7 +380,7 @@ pub fn compile_declarative_macro(
375
380
edition : Edition ,
376
381
) -> SyntaxExtension {
377
382
debug ! ( "compile_declarative_macro: {:?}" , def) ;
378
- let mk_syn_ext = |expander| {
383
+ let mk_syn_ext = |expander, rule_spans | {
379
384
SyntaxExtension :: new (
380
385
sess,
381
386
SyntaxExtensionKind :: LegacyBang ( expander) ,
@@ -384,8 +389,10 @@ pub fn compile_declarative_macro(
384
389
edition,
385
390
def. ident . name ,
386
391
& def. attrs ,
392
+ rule_spans,
387
393
)
388
394
} ;
395
+ let dummy_syn_ext = || mk_syn_ext ( Box :: new ( macro_rules_dummy_expander) , Vec :: new ( ) ) ;
389
396
390
397
let diag = & sess. parse_sess . span_diagnostic ;
391
398
let lhs_nm = Ident :: new ( sym:: lhs, def. span ) ;
@@ -446,17 +453,17 @@ pub fn compile_declarative_macro(
446
453
let s = parse_failure_msg ( & token) ;
447
454
let sp = token. span . substitute_dummy ( def. span ) ;
448
455
sess. parse_sess . span_diagnostic . struct_span_err ( sp, & s) . span_label ( sp, msg) . emit ( ) ;
449
- return mk_syn_ext ( Box :: new ( macro_rules_dummy_expander ) ) ;
456
+ return dummy_syn_ext ( ) ;
450
457
}
451
458
Error ( sp, msg) => {
452
459
sess. parse_sess
453
460
. span_diagnostic
454
461
. struct_span_err ( sp. substitute_dummy ( def. span ) , & msg)
455
462
. emit ( ) ;
456
- return mk_syn_ext ( Box :: new ( macro_rules_dummy_expander ) ) ;
463
+ return dummy_syn_ext ( ) ;
457
464
}
458
465
ErrorReported => {
459
- return mk_syn_ext ( Box :: new ( macro_rules_dummy_expander ) ) ;
466
+ return dummy_syn_ext ( ) ;
460
467
}
461
468
} ;
462
469
@@ -531,6 +538,11 @@ pub fn compile_declarative_macro(
531
538
None => { }
532
539
}
533
540
541
+ // Compute the spans of the macro rules
542
+ // We only take the span of the lhs here,
543
+ // so that the spans of created warnings are smaller.
544
+ let rule_spans = lhses. iter ( ) . map ( |lhs| lhs. span ( ) ) . collect :: < Vec < _ > > ( ) ;
545
+
534
546
// Convert the lhses into `MatcherLoc` form, which is better for doing the
535
547
// actual matching. Unless the matcher is invalid.
536
548
let lhses = if valid {
@@ -550,17 +562,21 @@ pub fn compile_declarative_macro(
550
562
vec ! [ ]
551
563
} ;
552
564
553
- mk_syn_ext ( Box :: new ( MacroRulesMacroExpander {
554
- name : def. ident ,
555
- span : def. span ,
556
- transparency,
557
- lhses,
558
- rhses,
559
- valid,
560
- // Macros defined in the current crate have a real node id,
561
- // whereas macros from an external crate have a dummy id.
562
- is_local : def. id != DUMMY_NODE_ID ,
563
- } ) )
565
+ mk_syn_ext (
566
+ Box :: new ( MacroRulesMacroExpander {
567
+ name : def. ident ,
568
+ span : def. span ,
569
+ id : def. id ,
570
+ transparency,
571
+ lhses,
572
+ rhses,
573
+ valid,
574
+ // Macros defined in the current crate have a real node id,
575
+ // whereas macros from an external crate have a dummy id.
576
+ is_local : def. id != DUMMY_NODE_ID ,
577
+ } ) ,
578
+ rule_spans,
579
+ )
564
580
}
565
581
566
582
fn check_lhs_nt_follows ( sess : & ParseSess , def : & ast:: Item , lhs : & mbe:: TokenTree ) -> bool {
0 commit comments