@@ -121,19 +121,41 @@ pub fn compile_input(trans: Box<TransCrate>,
121
121
} ;
122
122
123
123
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) ;
124
146
125
147
// Ensure the source file isn't accidentally overwritten during compilation.
126
148
match * input_path {
127
149
Some ( ref input_path) => {
128
150
if sess. opts . will_create_output_file ( ) {
129
- if outputs . contains_path ( input_path) {
151
+ if output_contains_path ( & output_paths , input_path) {
130
152
sess. err ( & format ! (
131
153
"the input file \" {}\" would be overwritten by the generated \
132
154
executable",
133
155
input_path. display( ) ) ) ;
134
156
return Err ( CompileIncomplete :: Stopped ) ;
135
157
}
136
- if let Some ( dir_path) = outputs . conflicts_with_dir ( ) {
158
+ if let Some ( dir_path) = output_conflicts_with_dir ( & output_paths ) {
137
159
sess. err ( & format ! (
138
160
"the generated executable for the input file \" {}\" conflicts with the \
139
161
existing directory \" {}\" ",
@@ -145,29 +167,7 @@ pub fn compile_input(trans: Box<TransCrate>,
145
167
None => { }
146
168
}
147
169
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) ;
171
171
if sess. opts . output_types . contains_key ( & OutputType :: DepInfo ) &&
172
172
sess. opts . output_types . keys ( ) . count ( ) == 1 {
173
173
return Ok ( ( ) )
@@ -1111,7 +1111,10 @@ fn escape_dep_filename(filename: &FileName) -> String {
1111
1111
filename. to_string ( ) . replace ( " " , "\\ " )
1112
1112
}
1113
1113
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 > {
1115
1118
let mut out_filenames = Vec :: new ( ) ;
1116
1119
for output_type in sess. opts . output_types . keys ( ) {
1117
1120
let file = outputs. path ( * output_type) ;
@@ -1135,7 +1138,46 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
1135
1138
}
1136
1139
}
1137
1140
}
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
+ }
1138
1177
1178
+ fn write_out_deps ( sess : & Session ,
1179
+ outputs : & OutputFilenames ,
1180
+ out_filenames : & Vec < PathBuf > ) {
1139
1181
// Write out dependency rules to the dep-info file if requested
1140
1182
if !sess. opts . output_types . contains_key ( & OutputType :: DepInfo ) {
1141
1183
return ;
@@ -1154,7 +1196,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
1154
1196
. map ( |fmap| escape_dep_filename ( & fmap. name ) )
1155
1197
. collect ( ) ;
1156
1198
let mut file = fs:: File :: create ( & deps_filename) ?;
1157
- for path in & out_filenames {
1199
+ for path in out_filenames {
1158
1200
write ! ( file, "{}: {}\n \n " , path. display( ) , files. join( " " ) ) ?;
1159
1201
}
1160
1202
0 commit comments