@@ -121,23 +121,8 @@ 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
-
125
- // Ensure the source file isn't accidentally overwritten during compilation.
126
- match * input_path {
127
- Some ( ref input_path) => {
128
- if outputs. contains_path ( input_path) && sess. opts . will_create_output_file ( ) {
129
- sess. err ( & format ! (
130
- "the input file \" {}\" would be overwritten by the generated executable" ,
131
- input_path. display( ) ) ) ;
132
- return Err ( CompileIncomplete :: Stopped ) ;
133
- }
134
- } ,
135
- None => { }
136
- }
137
-
138
124
let crate_name =
139
125
:: rustc_trans_utils:: link:: find_crate_name ( Some ( sess) , & krate. attrs , input) ;
140
-
141
126
let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
142
127
phase_2_configure_and_expand (
143
128
sess,
@@ -157,7 +142,29 @@ pub fn compile_input(trans: Box<TransCrate>,
157
142
) ?
158
143
} ;
159
144
160
- write_out_deps ( sess, & outputs, & crate_name) ;
145
+ let output_paths = generated_output_paths ( sess, & outputs, output. is_some ( ) , & crate_name) ;
146
+
147
+ // Ensure the source file isn't accidentally overwritten during compilation.
148
+ if let Some ( ref input_path) = * input_path {
149
+ if sess. opts . will_create_output_file ( ) {
150
+ if output_contains_path ( & output_paths, input_path) {
151
+ sess. err ( & format ! (
152
+ "the input file \" {}\" would be overwritten by the generated \
153
+ executable",
154
+ input_path. display( ) ) ) ;
155
+ return Err ( CompileIncomplete :: Stopped ) ;
156
+ }
157
+ if let Some ( dir_path) = output_conflicts_with_dir ( & output_paths) {
158
+ sess. err ( & format ! (
159
+ "the generated executable for the input file \" {}\" conflicts with the \
160
+ existing directory \" {}\" ",
161
+ input_path. display( ) , dir_path. display( ) ) ) ;
162
+ return Err ( CompileIncomplete :: Stopped ) ;
163
+ }
164
+ }
165
+ }
166
+
167
+ write_out_deps ( sess, & outputs, & output_paths) ;
161
168
if sess. opts . output_types . contains_key ( & OutputType :: DepInfo ) &&
162
169
sess. opts . output_types . keys ( ) . count ( ) == 1 {
163
170
return Ok ( ( ) )
@@ -1101,16 +1108,22 @@ fn escape_dep_filename(filename: &FileName) -> String {
1101
1108
filename. to_string ( ) . replace ( " " , "\\ " )
1102
1109
}
1103
1110
1104
- fn write_out_deps ( sess : & Session , outputs : & OutputFilenames , crate_name : & str ) {
1111
+ // Returns all the paths that correspond to generated files.
1112
+ fn generated_output_paths ( sess : & Session ,
1113
+ outputs : & OutputFilenames ,
1114
+ exact_name : bool ,
1115
+ crate_name : & str ) -> Vec < PathBuf > {
1105
1116
let mut out_filenames = Vec :: new ( ) ;
1106
1117
for output_type in sess. opts . output_types . keys ( ) {
1107
1118
let file = outputs. path ( * output_type) ;
1108
1119
match * output_type {
1109
- OutputType :: Exe => {
1110
- for output in sess. crate_types . borrow ( ) . iter ( ) {
1120
+ // If the filename has been overridden using `-o`, it will not be modified
1121
+ // by appending `.rlib`, `.exe`, etc., so we can skip this transformation.
1122
+ OutputType :: Exe if !exact_name => {
1123
+ for crate_type in sess. crate_types . borrow ( ) . iter ( ) {
1111
1124
let p = :: rustc_trans_utils:: link:: filename_for_input (
1112
1125
sess,
1113
- * output ,
1126
+ * crate_type ,
1114
1127
crate_name,
1115
1128
outputs
1116
1129
) ;
@@ -1125,7 +1138,46 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
1125
1138
}
1126
1139
}
1127
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
+ }
1128
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
+ }
1177
+
1178
+ fn write_out_deps ( sess : & Session ,
1179
+ outputs : & OutputFilenames ,
1180
+ out_filenames : & Vec < PathBuf > ) {
1129
1181
// Write out dependency rules to the dep-info file if requested
1130
1182
if !sess. opts . output_types . contains_key ( & OutputType :: DepInfo ) {
1131
1183
return ;
@@ -1144,7 +1196,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
1144
1196
. map ( |fmap| escape_dep_filename ( & fmap. name ) )
1145
1197
. collect ( ) ;
1146
1198
let mut file = fs:: File :: create ( & deps_filename) ?;
1147
- for path in & out_filenames {
1199
+ for path in out_filenames {
1148
1200
write ! ( file, "{}: {}\n \n " , path. display( ) , files. join( " " ) ) ?;
1149
1201
}
1150
1202
@@ -1327,7 +1379,10 @@ pub fn build_output_filenames(input: &Input,
1327
1379
Some ( out_file. clone ( ) )
1328
1380
} ;
1329
1381
if * odir != None {
1330
- sess. warn ( "ignoring --out-dir flag due to -o flag." ) ;
1382
+ sess. warn ( "ignoring --out-dir flag due to -o flag" ) ;
1383
+ }
1384
+ if !sess. opts . cg . extra_filename . is_empty ( ) {
1385
+ sess. warn ( "ignoring -C extra-filename flag due to -o flag" ) ;
1331
1386
}
1332
1387
1333
1388
let cur_dir = Path :: new ( "" ) ;
0 commit comments