diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2009e18f6ee20..9b400de2e89e6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -399,6 +399,33 @@ impl OutputFilenames { pub fn filestem(&self) -> String { format!("{}{}", self.out_filestem, self.extra) } + + pub fn is_path_used(&self, path: &PathBuf) -> bool { + fn eq(p1: &PathBuf, p2: &PathBuf) -> bool { + let p1 = match p1.canonicalize() { + Ok(p) => Some(p), + _ => None, + }; + let p2 = match p2.canonicalize() { + Ok(p) => Some(p), + _ => None, + }; + p1 == p2 + } + + match self.single_output_file { + Some(ref p) => eq(&p, path), + None => { + for k in self.outputs.keys() { + let opath: PathBuf = self.path(k.to_owned()); + if eq(&opath, path) { + return true; + } + } + false + } + } + } } pub fn host_triple() -> &'static str { @@ -455,6 +482,12 @@ impl Options { self.incremental.is_none() || self.cg.codegen_units == 1 } + + /// True if there will be an output file generated + pub fn will_create_output_file(&self) -> bool { + !self.debugging_opts.parse_only || // we will generate an output file and + self.debugging_opts.ls // we're not just querying an existing file + } } // The type of entry function, so diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index fbd48fc42c92d..92779da5b9b3e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -210,10 +210,26 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String], let codemap = Rc::new(CodeMap::with_file_loader(loader)); let sess = session::build_session_with_codemap(sopts, &dep_graph, - input_file_path, + input_file_path.clone(), descriptions, cstore.clone(), codemap); + + match input_file_path { + Some(ifile) => { + // This isn't used later in the compilation process, it's only used to check for + // overwrites of the source file. + if driver::build_output_filenames(&input, &odir, &ofile, &[], &sess) + .is_path_used(&ifile) && !sess.opts.will_create_output_file() { + sess.err(&format!( + "the input file \"{}\" would be overwritten by the generated executable", + ifile.display())); + return (Err(1), Some(sess)); + } + }, + None => (), + } + rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg); target_features::add_configuration(&mut cfg, &sess); diff --git a/src/test/run-make/output-filename-overwrites-input/Makefile b/src/test/run-make/output-filename-overwrites-input/Makefile new file mode 100644 index 0000000000000..f7f517fb4f8d9 --- /dev/null +++ b/src/test/run-make/output-filename-overwrites-input/Makefile @@ -0,0 +1,10 @@ +-include ../tools.mk + +all: + cp foo.rs $(TMPDIR)/foo + $(RUSTC) $(TMPDIR)/foo 2>&1 \ + | grep "the input file \".*foo\" would be overwritten by the generated executable" + $(RUSTC) foo.rs 2>&1 && $(RUSTC) -Z ls $(TMPDIR)/foo 2>&1 + cp foo.rs $(TMPDIR)/foo.rs + $(RUSTC) $(TMPDIR)/foo.rs -o $(TMPDIR)/foo.rs 2>&1 \ + | grep "the input file \".*foo.rs\" would be overwritten by the generated executable" diff --git a/src/test/run-make/output-filename-overwrites-input/foo.rs b/src/test/run-make/output-filename-overwrites-input/foo.rs new file mode 100644 index 0000000000000..8ae3d072362ed --- /dev/null +++ b/src/test/run-make/output-filename-overwrites-input/foo.rs @@ -0,0 +1,11 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() {} diff --git a/src/test/run-make/weird-output-filenames/Makefile b/src/test/run-make/weird-output-filenames/Makefile index 8b69c68279dca..ccc55cbfedda9 100644 --- a/src/test/run-make/weird-output-filenames/Makefile +++ b/src/test/run-make/weird-output-filenames/Makefile @@ -7,8 +7,8 @@ all: cp foo.rs $(TMPDIR)/.foo.bar $(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \ | grep "invalid character.*in crate name:" - cp foo.rs $(TMPDIR)/+foo+bar - $(RUSTC) $(TMPDIR)/+foo+bar 2>&1 \ + cp foo.rs $(TMPDIR)/+foo+bar.rs + $(RUSTC) $(TMPDIR)/+foo+bar.rs 2>&1 \ | grep "invalid character.*in crate name:" cp foo.rs $(TMPDIR)/-foo.rs $(RUSTC) $(TMPDIR)/-foo.rs 2>&1 \