@@ -25,6 +25,7 @@ use std::collections::HashSet;
2525use std:: env;
2626use std:: ffi:: OsString ;
2727use std:: fs:: { self , File , create_dir_all} ;
28+ use std:: fmt;
2829use std:: io:: prelude:: * ;
2930use std:: io:: { self , BufReader } ;
3031use std:: path:: { Path , PathBuf } ;
@@ -2237,7 +2238,7 @@ actual:\n\
22372238 let ( _, tests_text) = test_file_contents. split_at ( idx + "// END_RUST SOURCE" . len ( ) ) ;
22382239 let tests_text_str = String :: from ( tests_text) ;
22392240 let mut curr_test : Option < & str > = None ;
2240- let mut curr_test_contents = Vec :: new ( ) ;
2241+ let mut curr_test_contents = vec ! [ ExpectedLine :: Elision ] ;
22412242 for l in tests_text_str. lines ( ) {
22422243 debug ! ( "line: {:?}" , l) ;
22432244 if l. starts_with ( "// START " ) {
@@ -2251,11 +2252,14 @@ actual:\n\
22512252 self . compare_mir_test_output ( curr_test. unwrap ( ) , & curr_test_contents) ;
22522253 curr_test = None ;
22532254 curr_test_contents. clear ( ) ;
2255+ curr_test_contents. push ( ExpectedLine :: Elision ) ;
22542256 } else if l. is_empty ( ) {
22552257 // ignore
2258+ } else if l. starts_with ( "//" ) && l. split_at ( "//" . len ( ) ) . 1 . trim ( ) == "..." {
2259+ curr_test_contents. push ( ExpectedLine :: Elision )
22562260 } else if l. starts_with ( "// " ) {
22572261 let ( _, test_content) = l. split_at ( "// " . len ( ) ) ;
2258- curr_test_contents. push ( test_content) ;
2262+ curr_test_contents. push ( ExpectedLine :: Text ( test_content) ) ;
22592263 }
22602264 }
22612265 }
@@ -2273,7 +2277,7 @@ actual:\n\
22732277 }
22742278 }
22752279
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 > ] ) {
22772281 let mut output_file = PathBuf :: new ( ) ;
22782282 output_file. push ( self . get_mir_dump_dir ( ) ) ;
22792283 output_file. push ( test_name) ;
@@ -2285,38 +2289,77 @@ actual:\n\
22852289 let mut dumped_string = String :: new ( ) ;
22862290 dumped_file. read_to_string ( & mut dumped_string) . unwrap ( ) ;
22872291 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 ( ) ;
22892299
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| {
22932301 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
22962317 } ;
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 => { } ,
23202363 }
23212364 }
23222365 }
@@ -2439,6 +2482,25 @@ enum TargetLocation {
24392482 ThisDirectory ( PathBuf ) ,
24402483}
24412484
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+
24422504fn normalize_mir_line ( line : & str ) -> String {
24432505 nocomment_mir_line ( line) . replace ( char:: is_whitespace, "" )
24442506}
0 commit comments