@@ -26,7 +26,7 @@ use std::collections::VecDeque;
2626use std:: collections:: HashMap ;
2727use std:: collections:: HashSet ;
2828use std:: env;
29- use std:: ffi:: OsString ;
29+ use std:: ffi:: { OsStr , OsString } ;
3030use std:: fs:: { self , create_dir_all, File } ;
3131use std:: fmt;
3232use std:: io:: prelude:: * ;
@@ -72,6 +72,26 @@ impl Mismatch {
7272 }
7373}
7474
75+ trait PathBufExt {
76+ /// Append an extension to the path, even if it already has one.
77+ fn with_extra_extension < S : AsRef < OsStr > > ( & self , extension : S ) -> PathBuf ;
78+ }
79+
80+ impl PathBufExt for PathBuf {
81+ fn with_extra_extension < S : AsRef < OsStr > > ( & self , extension : S ) -> PathBuf {
82+ if extension. as_ref ( ) . len ( ) == 0 {
83+ self . clone ( )
84+ } else {
85+ let mut fname = self . file_name ( ) . unwrap ( ) . to_os_string ( ) ;
86+ if !extension. as_ref ( ) . to_str ( ) . unwrap ( ) . starts_with ( "." ) {
87+ fname. push ( "." ) ;
88+ }
89+ fname. push ( extension) ;
90+ self . with_file_name ( fname)
91+ }
92+ }
93+ }
94+
7595// Produces a diff between the expected output and actual output.
7696pub fn make_diff ( expected : & str , actual : & str , context_size : usize ) -> Vec < Mismatch > {
7797 let mut line_number = 1 ;
@@ -1725,20 +1745,14 @@ impl<'test> TestCx<'test> {
17251745 }
17261746
17271747 fn make_exe_name ( & self ) -> PathBuf {
1728- let mut f = self . output_base_name ( ) ;
1748+ let mut f = self . output_base_name_stage ( ) ;
17291749 // FIXME: This is using the host architecture exe suffix, not target!
17301750 if self . config . target . contains ( "emscripten" ) {
1731- let mut fname = f. file_name ( ) . unwrap ( ) . to_os_string ( ) ;
1732- fname. push ( ".js" ) ;
1733- f. set_file_name ( & fname) ;
1751+ f = f. with_extra_extension ( "js" ) ;
17341752 } else if self . config . target . contains ( "wasm32" ) {
1735- let mut fname = f. file_name ( ) . unwrap ( ) . to_os_string ( ) ;
1736- fname. push ( ".wasm" ) ;
1737- f. set_file_name ( & fname) ;
1753+ f = f. with_extra_extension ( "wasm" ) ;
17381754 } else if !env:: consts:: EXE_SUFFIX . is_empty ( ) {
1739- let mut fname = f. file_name ( ) . unwrap ( ) . to_os_string ( ) ;
1740- fname. push ( env:: consts:: EXE_SUFFIX ) ;
1741- f. set_file_name ( & fname) ;
1755+ f = f. with_extra_extension ( env:: consts:: EXE_SUFFIX ) ;
17421756 }
17431757 f
17441758 }
@@ -1846,25 +1860,28 @@ impl<'test> TestCx<'test> {
18461860 }
18471861
18481862 fn aux_output_dir_name ( & self ) -> PathBuf {
1849- let f = self . output_base_name ( ) ;
1850- let mut fname = f. file_name ( ) . unwrap ( ) . to_os_string ( ) ;
1851- fname. push ( & format ! ( "{}.aux" , self . config. mode. disambiguator( ) ) ) ;
1852- f. with_file_name ( & fname)
1863+ self . output_base_name_stage ( )
1864+ . with_extra_extension ( self . config . mode . disambiguator ( ) )
1865+ . with_extra_extension ( ".aux" )
18531866 }
18541867
18551868 fn output_testname ( & self , filepath : & Path ) -> PathBuf {
18561869 PathBuf :: from ( filepath. file_stem ( ) . unwrap ( ) )
18571870 }
18581871
1859- /// Given a test path like `compile-fail/foo/bar.rs` Returns a name like
1860- ///
1861- /// <output>/foo/bar-stage1
1872+ /// Given a test path like `compile-fail/foo/bar.rs` returns a name like
1873+ /// `/path/to/build/<triple>/test/compile-fail/foo/bar`.
18621874 fn output_base_name ( & self ) -> PathBuf {
18631875 let dir = self . config . build_base . join ( & self . testpaths . relative_dir ) ;
18641876
18651877 // Note: The directory `dir` is created during `collect_tests_from_dir`
18661878 dir. join ( & self . output_testname ( & self . testpaths . file ) )
1867- . with_extension ( & self . config . stage_id )
1879+ }
1880+
1881+ /// Same as `output_base_name`, but includes the stage ID as an extension,
1882+ /// such as: `.../compile-fail/foo/bar.stage1-<triple>`
1883+ fn output_base_name_stage ( & self ) -> PathBuf {
1884+ self . output_base_name ( ) . with_extension ( & self . config . stage_id )
18681885 }
18691886
18701887 fn maybe_dump_to_stdout ( & self , out : & str , err : & str ) {
@@ -1989,7 +2006,7 @@ impl<'test> TestCx<'test> {
19892006 fn run_rustdoc_test ( & self ) {
19902007 assert ! ( self . revision. is_none( ) , "revisions not relevant here" ) ;
19912008
1992- let out_dir = self . output_base_name ( ) ;
2009+ let out_dir = self . output_base_name_stage ( ) ;
19932010 let _ = fs:: remove_dir_all ( & out_dir) ;
19942011 create_dir_all ( & out_dir) . unwrap ( ) ;
19952012
@@ -2391,7 +2408,7 @@ impl<'test> TestCx<'test> {
23912408 . unwrap ( ) ;
23922409 let src_root = cwd. join ( & src_root) ;
23932410
2394- let tmpdir = cwd. join ( self . output_base_name ( ) ) ;
2411+ let tmpdir = cwd. join ( self . output_base_name_stage ( ) ) ;
23952412 if tmpdir. exists ( ) {
23962413 self . aggressive_rm_rf ( & tmpdir) . unwrap ( ) ;
23972414 }
@@ -2816,7 +2833,6 @@ impl<'test> TestCx<'test> {
28162833 self . revision ,
28172834 & self . config . compare_mode ,
28182835 kind) ;
2819-
28202836 if !path. exists ( ) && self . config . compare_mode . is_some ( ) {
28212837 // fallback!
28222838 path = expected_output_path ( & self . testpaths , self . revision , & None , kind) ;
@@ -2880,10 +2896,12 @@ impl<'test> TestCx<'test> {
28802896 }
28812897 }
28822898
2883- let expected_output = self . expected_output_path ( kind) ;
2884- // #50113: output is abspath; only want filename component.
2885- let expected_output = expected_output. file_name ( ) . expect ( "output path requires file name" ) ;
2886- let output_file = self . output_base_name ( ) . with_file_name ( & expected_output) ;
2899+ let mode = self . config . compare_mode . as_ref ( ) . map_or ( "" , |m| m. to_str ( ) ) ;
2900+ let output_file = self . output_base_name ( )
2901+ . with_extra_extension ( self . revision . unwrap_or ( "" ) )
2902+ . with_extra_extension ( mode)
2903+ . with_extra_extension ( kind) ;
2904+
28872905 match File :: create ( & output_file) . and_then ( |mut f| f. write_all ( actual. as_bytes ( ) ) ) {
28882906 Ok ( ( ) ) => { }
28892907 Err ( e) => self . fatal ( & format ! (
0 commit comments