2
2
3
3
use std:: path:: { Path , PathBuf } ;
4
4
use std:: str:: FromStr ;
5
+ use std:: sync:: OnceLock ;
5
6
7
+ use regex:: Regex ;
6
8
use serde:: Deserialize ;
7
9
8
10
use crate :: errors:: { Error , ErrorKind } ;
@@ -213,36 +215,24 @@ fn push_expected_errors(
213
215
// also ensure that `//~ ERROR E123` *always* works. The
214
216
// assumption is that these multi-line error messages are on their
215
217
// way out anyhow.
216
- let with_code = |span : & DiagnosticSpan , text : & str | {
217
- match diagnostic. code {
218
- Some ( ref code) =>
219
- // FIXME(#33000) -- it'd be better to use a dedicated
220
- // UI harness than to include the line/col number like
221
- // this, but some current tests rely on it.
222
- //
223
- // Note: Do NOT include the filename. These can easily
224
- // cause false matches where the expected message
225
- // appears in the filename, and hence the message
226
- // changes but the test still passes.
227
- {
228
- format ! (
229
- "{}:{}: {}:{}: {} [{}]" ,
230
- span. line_start,
231
- span. column_start,
232
- span. line_end,
233
- span. column_end,
234
- text,
235
- code. code. clone( )
236
- )
237
- }
238
- None =>
239
- // FIXME(#33000) -- it'd be better to use a dedicated UI harness
240
- {
241
- format ! (
242
- "{}:{}: {}:{}: {}" ,
243
- span. line_start, span. column_start, span. line_end, span. column_end, text
244
- )
218
+ let with_code = |span : Option < & DiagnosticSpan > , text : & str | {
219
+ // FIXME(#33000) -- it'd be better to use a dedicated
220
+ // UI harness than to include the line/col number like
221
+ // this, but some current tests rely on it.
222
+ //
223
+ // Note: Do NOT include the filename. These can easily
224
+ // cause false matches where the expected message
225
+ // appears in the filename, and hence the message
226
+ // changes but the test still passes.
227
+ let span_str = match span {
228
+ Some ( DiagnosticSpan { line_start, column_start, line_end, column_end, .. } ) => {
229
+ format ! ( "{line_start}:{column_start}: {line_end}:{column_end}" )
245
230
}
231
+ None => format ! ( "?:?: ?:?" ) ,
232
+ } ;
233
+ match & diagnostic. code {
234
+ Some ( code) => format ! ( "{span_str}: {text} [{}]" , code. code) ,
235
+ None => format ! ( "{span_str}: {text}" ) ,
246
236
}
247
237
} ;
248
238
@@ -251,19 +241,41 @@ fn push_expected_errors(
251
241
// more structured shortly anyhow.
252
242
let mut message_lines = diagnostic. message . lines ( ) ;
253
243
if let Some ( first_line) = message_lines. next ( ) {
254
- for span in primary_spans {
255
- let msg = with_code ( span, first_line) ;
244
+ let ignore = |s| {
245
+ static RE : OnceLock < Regex > = OnceLock :: new ( ) ;
246
+ RE . get_or_init ( || {
247
+ Regex :: new ( r"aborting due to \d+ previous errors?|\d+ warnings? emitted" ) . unwrap ( )
248
+ } )
249
+ . is_match ( s)
250
+ } ;
251
+
252
+ if primary_spans. is_empty ( ) && !ignore ( first_line) {
253
+ let msg = with_code ( None , first_line) ;
256
254
let kind = ErrorKind :: from_str ( & diagnostic. level ) . ok ( ) ;
257
- expected_errors. push ( Error { line_num : span. line_start , kind, msg } ) ;
255
+ expected_errors. push ( Error { line_num : None , kind, msg } ) ;
256
+ } else {
257
+ for span in primary_spans {
258
+ let msg = with_code ( Some ( span) , first_line) ;
259
+ let kind = ErrorKind :: from_str ( & diagnostic. level ) . ok ( ) ;
260
+ expected_errors. push ( Error { line_num : Some ( span. line_start ) , kind, msg } ) ;
261
+ }
258
262
}
259
263
}
260
264
for next_line in message_lines {
261
- for span in primary_spans {
265
+ if primary_spans. is_empty ( ) {
262
266
expected_errors. push ( Error {
263
- line_num : span . line_start ,
267
+ line_num : None ,
264
268
kind : None ,
265
- msg : with_code ( span , next_line) ,
269
+ msg : with_code ( None , next_line) ,
266
270
} ) ;
271
+ } else {
272
+ for span in primary_spans {
273
+ expected_errors. push ( Error {
274
+ line_num : Some ( span. line_start ) ,
275
+ kind : None ,
276
+ msg : with_code ( Some ( span) , next_line) ,
277
+ } ) ;
278
+ }
267
279
}
268
280
}
269
281
@@ -272,7 +284,7 @@ fn push_expected_errors(
272
284
if let Some ( ref suggested_replacement) = span. suggested_replacement {
273
285
for ( index, line) in suggested_replacement. lines ( ) . enumerate ( ) {
274
286
expected_errors. push ( Error {
275
- line_num : span. line_start + index,
287
+ line_num : Some ( span. line_start + index) ,
276
288
kind : Some ( ErrorKind :: Suggestion ) ,
277
289
msg : line. to_string ( ) ,
278
290
} ) ;
@@ -290,7 +302,7 @@ fn push_expected_errors(
290
302
// Add notes for any labels that appear in the message.
291
303
for span in spans_in_this_file. iter ( ) . filter ( |span| span. label . is_some ( ) ) {
292
304
expected_errors. push ( Error {
293
- line_num : span. line_start ,
305
+ line_num : Some ( span. line_start ) ,
294
306
kind : Some ( ErrorKind :: Note ) ,
295
307
msg : span. label . clone ( ) . unwrap ( ) ,
296
308
} ) ;
@@ -309,7 +321,7 @@ fn push_backtrace(
309
321
) {
310
322
if Path :: new ( & expansion. span . file_name ) == Path :: new ( & file_name) {
311
323
expected_errors. push ( Error {
312
- line_num : expansion. span . line_start ,
324
+ line_num : Some ( expansion. span . line_start ) ,
313
325
kind : Some ( ErrorKind :: Note ) ,
314
326
msg : format ! ( "in this expansion of {}" , expansion. macro_decl_name) ,
315
327
} ) ;
0 commit comments