@@ -25,6 +25,7 @@ use std::collections::HashSet;
25
25
use std:: env;
26
26
use std:: ffi:: OsString ;
27
27
use std:: fs:: { self , File , create_dir_all} ;
28
+ use std:: fmt;
28
29
use std:: io:: prelude:: * ;
29
30
use std:: io:: { self , BufReader } ;
30
31
use std:: path:: { Path , PathBuf } ;
@@ -2237,7 +2238,7 @@ actual:\n\
2237
2238
let ( _, tests_text) = test_file_contents. split_at ( idx + "// END_RUST SOURCE" . len ( ) ) ;
2238
2239
let tests_text_str = String :: from ( tests_text) ;
2239
2240
let mut curr_test : Option < & str > = None ;
2240
- let mut curr_test_contents = Vec :: new ( ) ;
2241
+ let mut curr_test_contents = vec ! [ ExpectedLine :: Elision ] ;
2241
2242
for l in tests_text_str. lines ( ) {
2242
2243
debug ! ( "line: {:?}" , l) ;
2243
2244
if l. starts_with ( "// START " ) {
@@ -2251,11 +2252,14 @@ actual:\n\
2251
2252
self . compare_mir_test_output ( curr_test. unwrap ( ) , & curr_test_contents) ;
2252
2253
curr_test = None ;
2253
2254
curr_test_contents. clear ( ) ;
2255
+ curr_test_contents. push ( ExpectedLine :: Elision ) ;
2254
2256
} else if l. is_empty ( ) {
2255
2257
// ignore
2258
+ } else if l. starts_with ( "//" ) && l. split_at ( "//" . len ( ) ) . 1 . trim ( ) == "..." {
2259
+ curr_test_contents. push ( ExpectedLine :: Elision )
2256
2260
} else if l. starts_with ( "// " ) {
2257
2261
let ( _, test_content) = l. split_at ( "// " . len ( ) ) ;
2258
- curr_test_contents. push ( test_content) ;
2262
+ curr_test_contents. push ( ExpectedLine :: Text ( test_content) ) ;
2259
2263
}
2260
2264
}
2261
2265
}
@@ -2273,7 +2277,7 @@ actual:\n\
2273
2277
}
2274
2278
}
2275
2279
2276
- fn compare_mir_test_output ( & self , test_name : & str , expected_content : & [ & str ] ) {
2280
+ fn compare_mir_test_output ( & self , test_name : & str , expected_content : & [ ExpectedLine < & str > ] ) {
2277
2281
let mut output_file = PathBuf :: new ( ) ;
2278
2282
output_file. push ( self . get_mir_dump_dir ( ) ) ;
2279
2283
output_file. push ( test_name) ;
@@ -2285,38 +2289,77 @@ actual:\n\
2285
2289
let mut dumped_string = String :: new ( ) ;
2286
2290
dumped_file. read_to_string ( & mut dumped_string) . unwrap ( ) ;
2287
2291
let mut dumped_lines = dumped_string. lines ( ) . filter ( |l| !l. is_empty ( ) ) ;
2288
- let mut expected_lines = expected_content. iter ( ) . filter ( |l| !l. is_empty ( ) ) ;
2292
+ let mut expected_lines = expected_content. iter ( ) . filter ( |& l| {
2293
+ if let & ExpectedLine :: Text ( l) = l {
2294
+ !l. is_empty ( )
2295
+ } else {
2296
+ true
2297
+ }
2298
+ } ) . peekable ( ) ;
2289
2299
2290
- // We expect each non-empty line from expected_content to appear
2291
- // in the dump in order, but there may be extra lines interleaved
2292
- while let Some ( expected_line) = expected_lines. next ( ) {
2300
+ let compare = |expected_line, dumped_line| {
2293
2301
let e_norm = normalize_mir_line ( expected_line) ;
2294
- if e_norm. is_empty ( ) {
2295
- continue ;
2302
+ let d_norm = normalize_mir_line ( dumped_line) ;
2303
+ debug ! ( "found: {:?}" , d_norm) ;
2304
+ debug ! ( "expected: {:?}" , e_norm) ;
2305
+ e_norm == d_norm
2306
+ } ;
2307
+
2308
+ let error = |expected_line, extra_msg| {
2309
+ let normalize_all = dumped_string. lines ( )
2310
+ . map ( nocomment_mir_line)
2311
+ . filter ( |l| !l. is_empty ( ) )
2312
+ . collect :: < Vec < _ > > ( )
2313
+ . join ( "\n " ) ;
2314
+ let f = |l : & ExpectedLine < _ > | match l {
2315
+ & ExpectedLine :: Elision => "... (elided)" . into ( ) ,
2316
+ & ExpectedLine :: Text ( t) => t
2296
2317
} ;
2297
- let mut found = false ;
2298
- while let Some ( dumped_line) = dumped_lines. next ( ) {
2299
- let d_norm = normalize_mir_line ( dumped_line) ;
2300
- debug ! ( "found: {:?}" , d_norm) ;
2301
- debug ! ( "expected: {:?}" , e_norm) ;
2302
- if e_norm == d_norm {
2303
- found = true ;
2304
- break ;
2305
- } ;
2306
- }
2307
- if !found {
2308
- let normalize_all = dumped_string. lines ( )
2309
- . map ( nocomment_mir_line)
2310
- . filter ( |l| !l. is_empty ( ) )
2311
- . collect :: < Vec < _ > > ( )
2312
- . join ( "\n " ) ;
2313
- panic ! ( "ran out of mir dump output to match against.\n \
2314
- Did not find expected line: {:?}\n \
2315
- Expected:\n {}\n \
2316
- Actual:\n {}",
2317
- expected_line,
2318
- expected_content. join( "\n " ) ,
2319
- normalize_all) ;
2318
+ let expected_content = expected_content. iter ( )
2319
+ . map ( |l| f ( l) )
2320
+ . collect :: < Vec < _ > > ( )
2321
+ . join ( "\n " ) ;
2322
+ panic ! ( "Did not find expected line, error: {}\n \
2323
+ Actual Line: {:?}\n \
2324
+ Expected:\n {}\n \
2325
+ Actual:\n {}",
2326
+ extra_msg,
2327
+ expected_line,
2328
+ expected_content,
2329
+ normalize_all) ;
2330
+ } ;
2331
+
2332
+ // We expect each non-empty line to appear consecutively, non-consecutive lines
2333
+ // must be separated by at least one Elision
2334
+ while let Some ( dumped_line) = dumped_lines. next ( ) {
2335
+ match expected_lines. next ( ) {
2336
+ Some ( & ExpectedLine :: Text ( expected_line) ) =>
2337
+ if !compare ( expected_line, dumped_line) {
2338
+ error ( expected_line,
2339
+ format ! ( "Mismatch in lines\n Expected Line: {:?}" , dumped_line) ) ;
2340
+ } ,
2341
+ Some ( & ExpectedLine :: Elision ) => {
2342
+ // skip any number of elisions in a row.
2343
+ while let Some ( & & ExpectedLine :: Elision ) = expected_lines. peek ( ) {
2344
+ expected_lines. next ( ) ;
2345
+ }
2346
+ if let Some ( & ExpectedLine :: Text ( expected_line) ) = expected_lines. next ( ) {
2347
+ let mut found = compare ( expected_line, dumped_line) ;
2348
+ if found {
2349
+ continue ;
2350
+ }
2351
+ while let Some ( dumped_line) = dumped_lines. next ( ) {
2352
+ found = compare ( expected_line, dumped_line) ;
2353
+ if found {
2354
+ break ;
2355
+ }
2356
+ }
2357
+ if !found {
2358
+ error ( expected_line, "ran out of mir dump to match against" . into ( ) ) ;
2359
+ }
2360
+ }
2361
+ } ,
2362
+ None => { } ,
2320
2363
}
2321
2364
}
2322
2365
}
@@ -2439,6 +2482,25 @@ enum TargetLocation {
2439
2482
ThisDirectory ( PathBuf ) ,
2440
2483
}
2441
2484
2485
+ #[ derive( Clone , PartialEq , Eq ) ]
2486
+ enum ExpectedLine < T : AsRef < str > > {
2487
+ Elision ,
2488
+ Text ( T )
2489
+ }
2490
+
2491
+ impl < T > fmt:: Debug for ExpectedLine < T >
2492
+ where
2493
+ T : AsRef < str > + fmt:: Debug
2494
+ {
2495
+ fn fmt ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
2496
+ if let & ExpectedLine :: Text ( ref t) = self {
2497
+ write ! ( formatter, "{:?}" , t)
2498
+ } else {
2499
+ write ! ( formatter, "\" ...\" (Elision)" )
2500
+ }
2501
+ }
2502
+ }
2503
+
2442
2504
fn normalize_mir_line ( line : & str ) -> String {
2443
2505
nocomment_mir_line ( line) . replace ( char:: is_whitespace, "" )
2444
2506
}
0 commit comments