From 45e962ecc023749fed2bb926c3386059c8e1407a Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 7 Jan 2018 01:11:23 +0000 Subject: [PATCH] Use correct output file paths for error checking --- src/librustc/session/config.rs | 39 -------------- src/librustc_driver/driver.rs | 96 ++++++++++++++++++++++++---------- 2 files changed, 69 insertions(+), 66 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index b04376000c0e2..af91e294db6db 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -548,45 +548,6 @@ impl OutputFilenames { pub fn filestem(&self) -> String { format!("{}{}", self.out_filestem, self.extra) } - - fn check_output(&self, f: F) -> Option where F: Fn(PathBuf) -> Option { - match self.single_output_file { - Some(ref output_path) => { - f(output_path.clone()) - }, - None => { - for k in self.outputs.keys() { - let output_path = self.path(k.to_owned()); - if let Some(result) = f(output_path) { - return Some(result); - } - } - None - } - } - } - - pub fn contains_path(&self, input_path: &PathBuf) -> bool { - let input_path = input_path.canonicalize().ok(); - if input_path.is_none() { - return false - } - let check = |output_path: PathBuf| { - if output_path.canonicalize().ok() == input_path { - Some(()) - } else { None } - }; - self.check_output(check).is_some() - } - - pub fn conflicts_with_dir(&self) -> Option { - let check = |output_path: PathBuf| { - if output_path.is_dir() { - Some(output_path) - } else { None } - }; - self.check_output(check) - } } pub fn host_triple() -> &'static str { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 05bf5e5a7d94d..a8ba795845fc9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -121,19 +121,41 @@ pub fn compile_input(trans: Box, }; let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess); + let crate_name = + ::rustc_trans_utils::link::find_crate_name(Some(sess), &krate.attrs, input); + let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = { + phase_2_configure_and_expand( + sess, + &cstore, + krate, + registry, + &crate_name, + addl_plugins, + control.make_glob_map, + |expanded_crate| { + let mut state = CompileState::state_after_expand( + input, sess, outdir, output, &cstore, expanded_crate, &crate_name, + ); + controller_entry_point!(after_expand, sess, state, Ok(())); + Ok(()) + } + )? + }; + + let output_paths = generated_output_paths(sess, &outputs, &crate_name); // Ensure the source file isn't accidentally overwritten during compilation. match *input_path { Some(ref input_path) => { if sess.opts.will_create_output_file() { - if outputs.contains_path(input_path) { + if output_contains_path(&output_paths, input_path) { sess.err(&format!( "the input file \"{}\" would be overwritten by the generated \ executable", input_path.display())); return Err(CompileIncomplete::Stopped); } - if let Some(dir_path) = outputs.conflicts_with_dir() { + if let Some(dir_path) = output_conflicts_with_dir(&output_paths) { sess.err(&format!( "the generated executable for the input file \"{}\" conflicts with the \ existing directory \"{}\"", @@ -145,29 +167,7 @@ pub fn compile_input(trans: Box, None => {} } - let crate_name = - ::rustc_trans_utils::link::find_crate_name(Some(sess), &krate.attrs, input); - - let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = { - phase_2_configure_and_expand( - sess, - &cstore, - krate, - registry, - &crate_name, - addl_plugins, - control.make_glob_map, - |expanded_crate| { - let mut state = CompileState::state_after_expand( - input, sess, outdir, output, &cstore, expanded_crate, &crate_name, - ); - controller_entry_point!(after_expand, sess, state, Ok(())); - Ok(()) - } - )? - }; - - write_out_deps(sess, &outputs, &crate_name); + write_out_deps(sess, &outputs, &output_paths); if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.keys().count() == 1 { return Ok(()) @@ -1111,7 +1111,10 @@ fn escape_dep_filename(filename: &FileName) -> String { filename.to_string().replace(" ", "\\ ") } -fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) { +// Returns all the paths that correspond to generated files. +fn generated_output_paths(sess: &Session, + outputs: &OutputFilenames, + crate_name: &str) -> Vec { let mut out_filenames = Vec::new(); for output_type in sess.opts.output_types.keys() { let file = outputs.path(*output_type); @@ -1135,7 +1138,46 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) { } } } + out_filenames +} + +// Runs `f` on every output file path and returns the first non-None result, or None if `f` +// returns None for every file path. +fn check_output(output_paths: &Vec, f: F) -> Option + where F: Fn(&PathBuf) -> Option { + for output_path in output_paths { + if let Some(result) = f(output_path) { + return Some(result); + } + } + None +} + +pub fn output_contains_path(output_paths: &Vec, input_path: &PathBuf) -> bool { + let input_path = input_path.canonicalize().ok(); + if input_path.is_none() { + return false + } + let check = |output_path: &PathBuf| { + if output_path.canonicalize().ok() == input_path { + Some(()) + } else { None } + }; + check_output(output_paths, check).is_some() +} + +pub fn output_conflicts_with_dir(output_paths: &Vec) -> Option { + let check = |output_path: &PathBuf| { + if output_path.is_dir() { + Some(output_path.clone()) + } else { None } + }; + check_output(output_paths, check) +} +fn write_out_deps(sess: &Session, + outputs: &OutputFilenames, + out_filenames: &Vec) { // Write out dependency rules to the dep-info file if requested if !sess.opts.output_types.contains_key(&OutputType::DepInfo) { return; @@ -1154,7 +1196,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) { .map(|fmap| escape_dep_filename(&fmap.name)) .collect(); let mut file = fs::File::create(&deps_filename)?; - for path in &out_filenames { + for path in out_filenames { write!(file, "{}: {}\n\n", path.display(), files.join(" "))?; }