@@ -337,7 +337,7 @@ fn expand_macro<'cx>(
337
337
return result;
338
338
}
339
339
340
- let Some ( ( token, label) ) = tracker. best_failure else {
340
+ let Some ( ( token, label, remaining_matcher ) ) = tracker. best_failure else {
341
341
return tracker. result . expect ( "must have encountered Error or ErrorReported" ) ;
342
342
} ;
343
343
@@ -351,6 +351,12 @@ fn expand_macro<'cx>(
351
351
352
352
annotate_doc_comment ( & mut err, sess. source_map ( ) , span) ;
353
353
354
+ if let Some ( span) = remaining_matcher. span ( ) {
355
+ err. span_note ( span, format ! ( "while trying to match {remaining_matcher}" ) ) ;
356
+ } else {
357
+ err. note ( format ! ( "while trying to match {remaining_matcher}" ) ) ;
358
+ }
359
+
354
360
// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
355
361
if let Some ( ( arg, comma_span) ) = arg. add_comma ( ) {
356
362
for lhs in lhses {
@@ -379,17 +385,22 @@ fn expand_macro<'cx>(
379
385
}
380
386
381
387
/// The tracker used for the slow error path that collects useful info for diagnostics.
382
- struct CollectTrackerAndEmitter < ' a , ' cx > {
388
+ struct CollectTrackerAndEmitter < ' a , ' cx , ' matcher > {
383
389
cx : & ' a mut ExtCtxt < ' cx > ,
390
+ remaining_matcher : Option < & ' matcher MatcherLoc > ,
384
391
/// Which arm's failure should we report? (the one furthest along)
385
- best_failure : Option < ( Token , & ' static str ) > ,
392
+ best_failure : Option < ( Token , & ' static str , MatcherLoc ) > ,
386
393
root_span : Span ,
387
394
result : Option < Box < dyn MacResult + ' cx > > ,
388
395
}
389
396
390
- impl < ' a , ' cx , ' matcher > Tracker < ' matcher > for CollectTrackerAndEmitter < ' a , ' cx > {
391
- fn before_match_loc ( & mut self , _parser : & TtParser , _matcher : & ' matcher MatcherLoc ) {
392
- // Empty for now.
397
+ impl < ' a , ' cx , ' matcher > Tracker < ' matcher > for CollectTrackerAndEmitter < ' a , ' cx , ' matcher > {
398
+ fn before_match_loc ( & mut self , parser : & TtParser , matcher : & ' matcher MatcherLoc ) {
399
+ if self . remaining_matcher . is_none ( )
400
+ || ( parser. has_no_remaining_items_for_step ( ) && * matcher != MatcherLoc :: Eof )
401
+ {
402
+ self . remaining_matcher = Some ( matcher) ;
403
+ }
393
404
}
394
405
395
406
fn after_arm ( & mut self , result : & NamedParseResult ) {
@@ -398,8 +409,16 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx>
398
409
unreachable ! ( "should not collect detailed info for successful macro match" ) ;
399
410
}
400
411
Failure ( token, msg) => match self . best_failure {
401
- Some ( ( ref best_token, _) ) if best_token. span . lo ( ) >= token. span . lo ( ) => { }
402
- _ => self . best_failure = Some ( ( token. clone ( ) , msg) ) ,
412
+ Some ( ( ref best_token, _, _) ) if best_token. span . lo ( ) >= token. span . lo ( ) => { }
413
+ _ => {
414
+ self . best_failure = Some ( (
415
+ token. clone ( ) ,
416
+ msg,
417
+ self . remaining_matcher
418
+ . expect ( "must have collected matcher already" )
419
+ . clone ( ) ,
420
+ ) )
421
+ }
403
422
} ,
404
423
Error ( err_sp, msg) => {
405
424
let span = err_sp. substitute_dummy ( self . root_span ) ;
@@ -415,9 +434,9 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx>
415
434
}
416
435
}
417
436
418
- impl < ' a , ' cx > CollectTrackerAndEmitter < ' a , ' cx > {
437
+ impl < ' a , ' cx > CollectTrackerAndEmitter < ' a , ' cx , ' _ > {
419
438
fn new ( cx : & ' a mut ExtCtxt < ' cx > , root_span : Span ) -> Self {
420
- Self { cx, best_failure : None , root_span, result : None }
439
+ Self { cx, remaining_matcher : None , best_failure : None , root_span, result : None }
421
440
}
422
441
}
423
442
0 commit comments