@@ -43,7 +43,7 @@ pub(super) fn failed_to_match_macro<'cx>(
43
43
return result;
44
44
}
45
45
46
- let Some ( ( token, label, remaining_matcher) ) = tracker. best_failure else {
46
+ let Some ( BestFailure { token, msg : label, remaining_matcher, .. } ) = tracker. best_failure else {
47
47
return DummyResult :: any ( sp) ;
48
48
} ;
49
49
@@ -95,11 +95,24 @@ struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
95
95
cx : & ' a mut ExtCtxt < ' cx > ,
96
96
remaining_matcher : Option < & ' matcher MatcherLoc > ,
97
97
/// Which arm's failure should we report? (the one furthest along)
98
- best_failure : Option < ( Token , & ' static str , MatcherLoc ) > ,
98
+ best_failure : Option < BestFailure > ,
99
99
root_span : Span ,
100
100
result : Option < Box < dyn MacResult + ' cx > > ,
101
101
}
102
102
103
+ struct BestFailure {
104
+ token : Token ,
105
+ position_in_tokenstream : usize ,
106
+ msg : & ' static str ,
107
+ remaining_matcher : MatcherLoc ,
108
+ }
109
+
110
+ impl BestFailure {
111
+ fn is_better_position ( & self , position : usize ) -> bool {
112
+ position > self . position_in_tokenstream
113
+ }
114
+ }
115
+
103
116
impl < ' a , ' cx , ' matcher > Tracker < ' matcher > for CollectTrackerAndEmitter < ' a , ' cx , ' matcher > {
104
117
fn before_match_loc ( & mut self , parser : & TtParser , matcher : & ' matcher MatcherLoc ) {
105
118
if self . remaining_matcher . is_none ( )
@@ -119,18 +132,25 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
119
132
"should not collect detailed info for successful macro match" ,
120
133
) ;
121
134
}
122
- Failure ( token, msg) => match self . best_failure {
123
- Some ( ( ref best_token, _, _) ) if best_token. span . lo ( ) >= token. span . lo ( ) => { }
124
- _ => {
125
- self . best_failure = Some ( (
126
- token. clone ( ) ,
135
+ Failure ( token, approx_position, msg) => {
136
+ debug ! ( ?token, ?msg, "a new failure of an arm" ) ;
137
+
138
+ if self
139
+ . best_failure
140
+ . as_ref ( )
141
+ . map_or ( true , |failure| failure. is_better_position ( * approx_position) )
142
+ {
143
+ self . best_failure = Some ( BestFailure {
144
+ token : token. clone ( ) ,
145
+ position_in_tokenstream : * approx_position,
127
146
msg,
128
- self . remaining_matcher
147
+ remaining_matcher : self
148
+ . remaining_matcher
129
149
. expect ( "must have collected matcher already" )
130
150
. clone ( ) ,
131
- ) )
151
+ } )
132
152
}
133
- } ,
153
+ }
134
154
Error ( err_sp, msg) => {
135
155
let span = err_sp. substitute_dummy ( self . root_span ) ;
136
156
self . cx . struct_span_err ( span, msg) . emit ( ) ;
0 commit comments