Warn when rustc output conflicts with existing directories
When the compiled executable would conflict with a directory, display a rustc error instead of a verbose and potentially-confusing linker error. This is a usability improvement, and doesn’t actually change behaviour with regards to compilation success. This addresses the concern in #35887.
This commit is contained in:
parent
6b99adeb11
commit
df1c61d303
4 changed files with 64 additions and 17 deletions
|
@ -549,23 +549,43 @@ impl OutputFilenames {
|
||||||
format!("{}{}", self.out_filestem, self.extra)
|
format!("{}{}", self.out_filestem, self.extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_output<F, T>(&self, f: F) -> Option<T> where F: Fn(PathBuf) -> Option<T> {
|
||||||
|
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 {
|
pub fn contains_path(&self, input_path: &PathBuf) -> bool {
|
||||||
let input_path = input_path.canonicalize().ok();
|
let input_path = input_path.canonicalize().ok();
|
||||||
if input_path.is_none() {
|
if input_path.is_none() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
match self.single_output_file {
|
let check = |output_path: PathBuf| {
|
||||||
Some(ref output_path) => output_path.canonicalize().ok() == input_path,
|
|
||||||
None => {
|
|
||||||
for k in self.outputs.keys() {
|
|
||||||
let output_path = self.path(k.to_owned());
|
|
||||||
if output_path.canonicalize().ok() == input_path {
|
if output_path.canonicalize().ok() == input_path {
|
||||||
return true;
|
Some(())
|
||||||
}
|
} else { None }
|
||||||
}
|
};
|
||||||
false
|
self.check_output(check).is_some()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn conflicts_with_dir(&self) -> Option<PathBuf> {
|
||||||
|
let check = |output_path: PathBuf| {
|
||||||
|
if output_path.is_dir() {
|
||||||
|
Some(output_path)
|
||||||
|
} else { None }
|
||||||
|
};
|
||||||
|
self.check_output(check)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,12 +125,21 @@ pub fn compile_input(trans: Box<TransCrate>,
|
||||||
// Ensure the source file isn't accidentally overwritten during compilation.
|
// Ensure the source file isn't accidentally overwritten during compilation.
|
||||||
match *input_path {
|
match *input_path {
|
||||||
Some(ref input_path) => {
|
Some(ref input_path) => {
|
||||||
if outputs.contains_path(input_path) && sess.opts.will_create_output_file() {
|
if sess.opts.will_create_output_file() {
|
||||||
|
if outputs.contains_path(input_path) {
|
||||||
sess.err(&format!(
|
sess.err(&format!(
|
||||||
"the input file \"{}\" would be overwritten by the generated executable",
|
"the input file \"{}\" would be overwritten by the generated executable",
|
||||||
input_path.display()));
|
input_path.display()));
|
||||||
return Err(CompileIncomplete::Stopped);
|
return Err(CompileIncomplete::Stopped);
|
||||||
}
|
}
|
||||||
|
if let Some(dir_path) = outputs.conflicts_with_dir() {
|
||||||
|
sess.err(&format!(
|
||||||
|
"the generated executable for the input file \"{}\" conflicts with the \
|
||||||
|
existing directory \"{}\'",
|
||||||
|
input_path.display(), dir_path.display()));
|
||||||
|
return Err(CompileIncomplete::Stopped);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-include ../tools.mk
|
||||||
|
|
||||||
|
all:
|
||||||
|
cp foo.rs $(TMPDIR)/foo.rs
|
||||||
|
mkdir $(TMPDIR)/foo
|
||||||
|
$(RUSTC) $(TMPDIR)/foo.rs 2>&1 \
|
||||||
|
| $(CGREP) -e "the generated executable for the input file \".*foo\.rs\" conflicts with the existing directory \".*foo\'"
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2017 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in a new issue