@@ -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 ;
@@ -1240,16 +1240,10 @@ impl<'test> TestCx<'test> {
12401240 ) ) ;
12411241 }
12421242 }
1243-
12441243 let mut missing_patterns: Vec < String > = Vec :: new ( ) ;
12451244
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- }
1245+ self . check_error_patterns ( output_to_check, & mut missing_patterns) ;
1246+ self . check_regex_error_patterns ( output_to_check, proc_res, & mut missing_patterns) ;
12531247
12541248 if missing_patterns. is_empty ( ) {
12551249 return ;
@@ -1268,6 +1262,44 @@ impl<'test> TestCx<'test> {
12681262 }
12691263 }
12701264
1265+ fn check_error_patterns ( & self , output_to_check : & str , missing_patterns : & mut Vec < String > ) {
1266+ debug ! ( "check_error_patterns" ) ;
1267+ for pattern in & self . props . error_patterns {
1268+ if output_to_check. contains ( pattern. trim ( ) ) {
1269+ debug ! ( "found error pattern {}" , pattern) ;
1270+ } else {
1271+ missing_patterns. push ( pattern. to_string ( ) ) ;
1272+ }
1273+ }
1274+ }
1275+
1276+ fn check_regex_error_patterns (
1277+ & self ,
1278+ output_to_check : & str ,
1279+ proc_res : & ProcRes ,
1280+ missing_patterns : & mut Vec < String > ,
1281+ ) {
1282+ debug ! ( "check_regex_error_patterns" ) ;
1283+
1284+ for pattern in & self . props . regex_error_patterns {
1285+ let pattern = pattern. trim ( ) ;
1286+ let re = match Regex :: new ( pattern) {
1287+ Ok ( re) => re,
1288+ Err ( err) => {
1289+ self . fatal_proc_rec (
1290+ & format ! ( "invalid regex error pattern '{}': {:?}" , pattern, err) ,
1291+ proc_res,
1292+ ) ;
1293+ }
1294+ } ;
1295+ if re. is_match ( output_to_check) {
1296+ debug ! ( "found regex error pattern {}" , pattern) ;
1297+ } else {
1298+ missing_patterns. push ( pattern. to_string ( ) ) ;
1299+ }
1300+ }
1301+ }
1302+
12711303 fn check_no_compiler_crash ( & self , proc_res : & ProcRes , should_ice : bool ) {
12721304 match proc_res. status . code ( ) {
12731305 Some ( 101 ) if !should_ice => {
@@ -1892,7 +1924,9 @@ impl<'test> TestCx<'test> {
18921924 // If we are extracting and matching errors in the new
18931925 // fashion, then you want JSON mode. Old-skool error
18941926 // patterns still match the raw compiler output.
1895- if self . props . error_patterns . is_empty ( ) {
1927+ if self . props . error_patterns . is_empty ( )
1928+ && self . props . regex_error_patterns . is_empty ( )
1929+ {
18961930 rustc. args ( & [ "--error-format" , "json" ] ) ;
18971931 rustc. args ( & [ "--json" , "future-incompat" ] ) ;
18981932 }
@@ -3268,10 +3302,11 @@ impl<'test> TestCx<'test> {
32683302 self . fatal_proc_rec ( "test run succeeded!" , & proc_res) ;
32693303 }
32703304
3271- if !self . props . error_patterns . is_empty ( ) {
3305+ if !self . props . error_patterns . is_empty ( ) || !self . props . regex_error_patterns . is_empty ( )
3306+ {
32723307 // "// error-pattern" comments
32733308 let output_to_check = self . get_output ( & proc_res) ;
3274- self . check_error_patterns ( & output_to_check, & proc_res, pm) ;
3309+ self . check_all_error_patterns ( & output_to_check, & proc_res, pm) ;
32753310 }
32763311 }
32773312
@@ -3285,15 +3320,16 @@ impl<'test> TestCx<'test> {
32853320 self . props. error_patterns
32863321 ) ;
32873322 if !explicit && self . config . compare_mode . is_none ( ) {
3288- let check_patterns =
3289- should_run == WillExecute :: No && !self . props . error_patterns . is_empty ( ) ;
3323+ let check_patterns = should_run == WillExecute :: No
3324+ && ( !self . props . error_patterns . is_empty ( )
3325+ || !self . props . regex_error_patterns . is_empty ( ) ) ;
32903326
32913327 let check_annotations = !check_patterns || !expected_errors. is_empty ( ) ;
32923328
32933329 if check_patterns {
32943330 // "// error-pattern" comments
32953331 let output_to_check = self . get_output ( & proc_res) ;
3296- self . check_error_patterns ( & output_to_check, & proc_res, pm) ;
3332+ self . check_all_error_patterns ( & output_to_check, & proc_res, pm) ;
32973333 }
32983334
32993335 if check_annotations {
0 commit comments