@@ -323,12 +323,13 @@ impl<'test> TestCx<'test> {
323323 let output_to_check = self . get_output ( & proc_res) ;
324324 let expected_errors = errors:: load_errors ( & self . testpaths . file , self . revision ) ;
325325 if !expected_errors. is_empty ( ) {
326- if !self . props . error_patterns . is_empty ( ) {
326+ if !self . props . error_patterns . is_empty ( ) || !self . props . regex_error_patterns . is_empty ( )
327+ {
327328 self . fatal ( "both error pattern and expected errors specified" ) ;
328329 }
329330 self . check_expected_errors ( expected_errors, & proc_res) ;
330331 } else {
331- self . check_error_patterns ( & output_to_check, & proc_res, pm) ;
332+ self . check_all_error_patterns ( & output_to_check, & proc_res, pm) ;
332333 }
333334 if self . props . should_ice {
334335 match proc_res. status . code ( ) {
@@ -363,7 +364,7 @@ impl<'test> TestCx<'test> {
363364
364365 let output_to_check = self . get_output ( & proc_res) ;
365366 self . check_correct_failure_status ( & proc_res) ;
366- self . check_error_patterns ( & output_to_check, & proc_res, pm) ;
367+ self . check_all_error_patterns ( & output_to_check, & proc_res, pm) ;
367368 }
368369
369370 fn get_output ( & self , proc_res : & ProcRes ) -> String {
@@ -1222,14 +1223,13 @@ impl<'test> TestCx<'test> {
12221223 }
12231224 }
12241225
1225- fn check_error_patterns (
1226+ fn check_all_error_patterns (
12261227 & self ,
12271228 output_to_check : & str ,
12281229 proc_res : & ProcRes ,
12291230 pm : Option < PassMode > ,
12301231 ) {
1231- debug ! ( "check_error_patterns" ) ;
1232- if self . props . error_patterns . is_empty ( ) {
1232+ if self . props . error_patterns . is_empty ( ) && self . props . regex_error_patterns . is_empty ( ) {
12331233 if pm. is_some ( ) {
12341234 // FIXME(#65865)
12351235 return ;
@@ -1243,13 +1243,8 @@ impl<'test> TestCx<'test> {
12431243
12441244 let mut missing_patterns: Vec < String > = Vec :: new ( ) ;
12451245
1246- for pattern in & self . props . error_patterns {
1247- if output_to_check. contains ( pattern. trim ( ) ) {
1248- debug ! ( "found error pattern {}" , pattern) ;
1249- } else {
1250- missing_patterns. push ( pattern. to_string ( ) ) ;
1251- }
1252- }
1246+ self . check_error_patterns ( output_to_check, & mut missing_patterns) ;
1247+ self . check_regex_error_patterns ( output_to_check, proc_res, & mut missing_patterns) ;
12531248
12541249 if missing_patterns. is_empty ( ) {
12551250 return ;
@@ -1268,6 +1263,44 @@ impl<'test> TestCx<'test> {
12681263 }
12691264 }
12701265
1266+ fn check_error_patterns ( & self , output_to_check : & str , missing_patterns : & mut Vec < String > ) {
1267+ debug ! ( "check_error_patterns" ) ;
1268+ for pattern in & self . props . error_patterns {
1269+ if output_to_check. contains ( pattern. trim ( ) ) {
1270+ debug ! ( "found error pattern {}" , pattern) ;
1271+ } else {
1272+ missing_patterns. push ( pattern. to_string ( ) ) ;
1273+ }
1274+ }
1275+ }
1276+
1277+ fn check_regex_error_patterns (
1278+ & self ,
1279+ output_to_check : & str ,
1280+ proc_res : & ProcRes ,
1281+ missing_patterns : & mut Vec < String > ,
1282+ ) {
1283+ debug ! ( "check_regex_error_patterns" ) ;
1284+
1285+ for pattern in & self . props . regex_error_patterns {
1286+ let pattern = pattern. trim ( ) ;
1287+ let re = match Regex :: new ( pattern) {
1288+ Ok ( re) => re,
1289+ Err ( err) => {
1290+ self . fatal_proc_rec (
1291+ & format ! ( "invalid regex error pattern '{}': {:?}" , pattern, err) ,
1292+ proc_res,
1293+ ) ;
1294+ }
1295+ } ;
1296+ if re. is_match ( output_to_check) {
1297+ debug ! ( "found regex error pattern {}" , pattern) ;
1298+ } else {
1299+ missing_patterns. push ( pattern. to_string ( ) ) ;
1300+ }
1301+ }
1302+ }
1303+
12711304 fn check_no_compiler_crash ( & self , proc_res : & ProcRes , should_ice : bool ) {
12721305 match proc_res. status . code ( ) {
12731306 Some ( 101 ) if !should_ice => {
@@ -1892,7 +1925,9 @@ impl<'test> TestCx<'test> {
18921925 // If we are extracting and matching errors in the new
18931926 // fashion, then you want JSON mode. Old-skool error
18941927 // patterns still match the raw compiler output.
1895- if self . props . error_patterns . is_empty ( ) {
1928+ if self . props . error_patterns . is_empty ( )
1929+ && self . props . regex_error_patterns . is_empty ( )
1930+ {
18961931 rustc. args ( & [ "--error-format" , "json" ] ) ;
18971932 rustc. args ( & [ "--json" , "future-incompat" ] ) ;
18981933 }
@@ -3268,10 +3303,11 @@ impl<'test> TestCx<'test> {
32683303 self . fatal_proc_rec ( "test run succeeded!" , & proc_res) ;
32693304 }
32703305
3271- if !self . props . error_patterns . is_empty ( ) {
3306+ if !self . props . error_patterns . is_empty ( ) || !self . props . regex_error_patterns . is_empty ( )
3307+ {
32723308 // "// error-pattern" comments
32733309 let output_to_check = self . get_output ( & proc_res) ;
3274- self . check_error_patterns ( & output_to_check, & proc_res, pm) ;
3310+ self . check_all_error_patterns ( & output_to_check, & proc_res, pm) ;
32753311 }
32763312 }
32773313
@@ -3285,15 +3321,16 @@ impl<'test> TestCx<'test> {
32853321 self . props. error_patterns
32863322 ) ;
32873323 if !explicit && self . config . compare_mode . is_none ( ) {
3288- let check_patterns =
3289- should_run == WillExecute :: No && !self . props . error_patterns . is_empty ( ) ;
3324+ let check_patterns = should_run == WillExecute :: No
3325+ && ( !self . props . error_patterns . is_empty ( )
3326+ || !self . props . regex_error_patterns . is_empty ( ) ) ;
32903327
32913328 let check_annotations = !check_patterns || !expected_errors. is_empty ( ) ;
32923329
32933330 if check_patterns {
32943331 // "// error-pattern" comments
32953332 let output_to_check = self . get_output ( & proc_res) ;
3296- self . check_error_patterns ( & output_to_check, & proc_res, pm) ;
3333+ self . check_all_error_patterns ( & output_to_check, & proc_res, pm) ;
32973334 }
32983335
32993336 if check_annotations {
0 commit comments