@@ -121,19 +121,41 @@ pub fn compile_input(trans: Box<TransCrate>,
121121 } ;
122122
123123 let outputs = build_output_filenames ( input, outdir, output, & krate. attrs , sess) ;
124+ let crate_name =
125+ :: rustc_trans_utils:: link:: find_crate_name ( Some ( sess) , & krate. attrs , input) ;
126+ let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
127+ phase_2_configure_and_expand (
128+ sess,
129+ & cstore,
130+ krate,
131+ registry,
132+ & crate_name,
133+ addl_plugins,
134+ control. make_glob_map ,
135+ |expanded_crate| {
136+ let mut state = CompileState :: state_after_expand (
137+ input, sess, outdir, output, & cstore, expanded_crate, & crate_name,
138+ ) ;
139+ controller_entry_point ! ( after_expand, sess, state, Ok ( ( ) ) ) ;
140+ Ok ( ( ) )
141+ }
142+ ) ?
143+ } ;
144+
145+ let output_paths = generated_output_paths ( sess, & outputs, & crate_name) ;
124146
125147 // Ensure the source file isn't accidentally overwritten during compilation.
126148 match * input_path {
127149 Some ( ref input_path) => {
128150 if sess. opts . will_create_output_file ( ) {
129- if outputs . contains_path ( input_path) {
151+ if output_contains_path ( & output_paths , input_path) {
130152 sess. err ( & format ! (
131153 "the input file \" {}\" would be overwritten by the generated \
132154 executable",
133155 input_path. display( ) ) ) ;
134156 return Err ( CompileIncomplete :: Stopped ) ;
135157 }
136- if let Some ( dir_path) = outputs . conflicts_with_dir ( ) {
158+ if let Some ( dir_path) = output_conflicts_with_dir ( & output_paths ) {
137159 sess. err ( & format ! (
138160 "the generated executable for the input file \" {}\" conflicts with the \
139161 existing directory \" {}\" ",
@@ -145,29 +167,7 @@ pub fn compile_input(trans: Box<TransCrate>,
145167 None => { }
146168 }
147169
148- let crate_name =
149- :: rustc_trans_utils:: link:: find_crate_name ( Some ( sess) , & krate. attrs , input) ;
150-
151- let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
152- phase_2_configure_and_expand (
153- sess,
154- & cstore,
155- krate,
156- registry,
157- & crate_name,
158- addl_plugins,
159- control. make_glob_map ,
160- |expanded_crate| {
161- let mut state = CompileState :: state_after_expand (
162- input, sess, outdir, output, & cstore, expanded_crate, & crate_name,
163- ) ;
164- controller_entry_point ! ( after_expand, sess, state, Ok ( ( ) ) ) ;
165- Ok ( ( ) )
166- }
167- ) ?
168- } ;
169-
170- write_out_deps ( sess, & outputs, & crate_name) ;
170+ write_out_deps ( sess, & outputs, & output_paths) ;
171171 if sess. opts . output_types . contains_key ( & OutputType :: DepInfo ) &&
172172 sess. opts . output_types . keys ( ) . count ( ) == 1 {
173173 return Ok ( ( ) )
@@ -1111,7 +1111,10 @@ fn escape_dep_filename(filename: &FileName) -> String {
11111111 filename. to_string ( ) . replace ( " " , "\\ " )
11121112}
11131113
1114- fn write_out_deps ( sess : & Session , outputs : & OutputFilenames , crate_name : & str ) {
1114+ // Returns all the paths that correspond to generated files.
1115+ fn generated_output_paths ( sess : & Session ,
1116+ outputs : & OutputFilenames ,
1117+ crate_name : & str ) -> Vec < PathBuf > {
11151118 let mut out_filenames = Vec :: new ( ) ;
11161119 for output_type in sess. opts . output_types . keys ( ) {
11171120 let file = outputs. path ( * output_type) ;
@@ -1135,7 +1138,46 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
11351138 }
11361139 }
11371140 }
1141+ out_filenames
1142+ }
1143+
1144+ // Runs `f` on every output file path and returns the first non-None result, or None if `f`
1145+ // returns None for every file path.
1146+ fn check_output < F , T > ( output_paths : & Vec < PathBuf > , f : F ) -> Option < T >
1147+ where F : Fn ( & PathBuf ) -> Option < T > {
1148+ for output_path in output_paths {
1149+ if let Some ( result) = f ( output_path) {
1150+ return Some ( result) ;
1151+ }
1152+ }
1153+ None
1154+ }
1155+
1156+ pub fn output_contains_path ( output_paths : & Vec < PathBuf > , input_path : & PathBuf ) -> bool {
1157+ let input_path = input_path. canonicalize ( ) . ok ( ) ;
1158+ if input_path. is_none ( ) {
1159+ return false
1160+ }
1161+ let check = |output_path : & PathBuf | {
1162+ if output_path. canonicalize ( ) . ok ( ) == input_path {
1163+ Some ( ( ) )
1164+ } else { None }
1165+ } ;
1166+ check_output ( output_paths, check) . is_some ( )
1167+ }
1168+
1169+ pub fn output_conflicts_with_dir ( output_paths : & Vec < PathBuf > ) -> Option < PathBuf > {
1170+ let check = |output_path : & PathBuf | {
1171+ if output_path. is_dir ( ) {
1172+ Some ( output_path. clone ( ) )
1173+ } else { None }
1174+ } ;
1175+ check_output ( output_paths, check)
1176+ }
11381177
1178+ fn write_out_deps ( sess : & Session ,
1179+ outputs : & OutputFilenames ,
1180+ out_filenames : & Vec < PathBuf > ) {
11391181 // Write out dependency rules to the dep-info file if requested
11401182 if !sess. opts . output_types . contains_key ( & OutputType :: DepInfo ) {
11411183 return ;
@@ -1154,7 +1196,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
11541196 . map ( |fmap| escape_dep_filename ( & fmap. name ) )
11551197 . collect ( ) ;
11561198 let mut file = fs:: File :: create ( & deps_filename) ?;
1157- for path in & out_filenames {
1199+ for path in out_filenames {
11581200 write ! ( file, "{}: {}\n \n " , path. display( ) , files. join( " " ) ) ?;
11591201 }
11601202
0 commit comments