1
Fork 0

Make arg_expand_all not short-circuit on first error

This commit is contained in:
beetrees 2023-05-15 18:34:32 +00:00
parent 7d3702e472
commit 63091b105d
No known key found for this signature in database
GPG key ID: 8791BD754191EBD6
42 changed files with 270 additions and 53 deletions

View file

@ -4,6 +4,7 @@ use std::fs;
use std::io; use std::io;
use rustc_session::EarlyDiagCtxt; use rustc_session::EarlyDiagCtxt;
use rustc_span::ErrorGuaranteed;
/// Expands argfiles in command line arguments. /// Expands argfiles in command line arguments.
#[derive(Default)] #[derive(Default)]
@ -86,7 +87,7 @@ impl Expander {
fn read_file(path: &str) -> Result<String, Error> { fn read_file(path: &str) -> Result<String, Error> {
fs::read_to_string(path).map_err(|e| { fs::read_to_string(path).map_err(|e| {
if e.kind() == io::ErrorKind::InvalidData { if e.kind() == io::ErrorKind::InvalidData {
Error::Utf8Error(Some(path.to_string())) Error::Utf8Error(path.to_string())
} else { } else {
Error::IOError(path.to_string(), e) Error::IOError(path.to_string(), e)
} }
@ -94,23 +95,30 @@ impl Expander {
} }
} }
/// Replaces any `@file` arguments with the contents of `file`, with each line of `file` as a
/// separate argument.
///
/// **Note:** This function doesn't interpret argument 0 in any special way. /// **Note:** This function doesn't interpret argument 0 in any special way.
/// If this function is intended to be used with command line arguments, /// If this function is intended to be used with command line arguments,
/// `argv[0]` must be removed prior to calling it manually. /// `argv[0]` must be removed prior to calling it manually.
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<String> { pub fn arg_expand_all(
early_dcx: &EarlyDiagCtxt,
at_args: &[String],
) -> Result<Vec<String>, ErrorGuaranteed> {
let mut expander = Expander::default(); let mut expander = Expander::default();
let mut result = Ok(());
for arg in at_args { for arg in at_args {
if let Err(err) = expander.arg(arg) { if let Err(err) = expander.arg(arg) {
early_dcx.early_fatal(format!("Failed to load argument file: {err}")); result = Err(early_dcx.early_err(format!("failed to load argument file: {err}")));
} }
} }
expander.finish() result.map(|()| expander.finish())
} }
#[derive(Debug)] #[derive(Debug)]
pub enum Error { enum Error {
Utf8Error(Option<String>), Utf8Error(String),
IOError(String, io::Error), IOError(String, io::Error),
ShellParseError(String), ShellParseError(String),
} }
@ -118,10 +126,9 @@ pub enum Error {
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Error::Utf8Error(None) => write!(fmt, "Utf8 error"), Error::Utf8Error(path) => write!(fmt, "UTF-8 error in {path}"),
Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {path}"), Error::IOError(path, err) => write!(fmt, "IO error: {path}: {err}"),
Error::IOError(path, err) => write!(fmt, "IO Error: {path}: {err}"), Error::ShellParseError(path) => write!(fmt, "invalid shell-style arguments in {path}"),
Error::ShellParseError(path) => write!(fmt, "Invalid shell-style arguments in {path}"),
} }
} }
} }

View file

@ -292,7 +292,7 @@ fn run_compiler(
// the compiler with @empty_file as argv[0] and no more arguments. // the compiler with @empty_file as argv[0] and no more arguments.
let at_args = at_args.get(1..).unwrap_or_default(); let at_args = at_args.get(1..).unwrap_or_default();
let args = args::arg_expand_all(&default_early_dcx, at_args); let args = args::arg_expand_all(&default_early_dcx, at_args)?;
let Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) }; let Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) };

View file

@ -705,7 +705,7 @@ fn main_args(
// the compiler with @empty_file as argv[0] and no more arguments. // the compiler with @empty_file as argv[0] and no more arguments.
let at_args = at_args.get(1..).unwrap_or_default(); let at_args = at_args.get(1..).unwrap_or_default();
let args = rustc_driver::args::arg_expand_all(early_dcx, at_args); let args = rustc_driver::args::arg_expand_all(early_dcx, at_args)?;
let mut options = getopts::Options::new(); let mut options = getopts::Options::new();
for option in opts() { for option in opts() {

View file

@ -18,7 +18,7 @@ const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually. // FIXME: The following limits should be reduced eventually.
const ISSUES_ENTRY_LIMIT: usize = 1750; const ISSUES_ENTRY_LIMIT: usize = 1750;
const ROOT_ENTRY_LIMIT: usize = 872; const ROOT_ENTRY_LIMIT: usize = 866;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files "rs", // test source files
@ -34,8 +34,8 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
"tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint "tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint
"tests/ui/codegen/mismatched-data-layout.json", // testing mismatched data layout w/ custom targets "tests/ui/codegen/mismatched-data-layout.json", // testing mismatched data layout w/ custom targets
"tests/ui/check-cfg/my-awesome-platform.json", // testing custom targets with cfgs "tests/ui/check-cfg/my-awesome-platform.json", // testing custom targets with cfgs
"tests/ui/commandline-argfile-badutf8.args", // passing args via a file "tests/ui/argfile/commandline-argfile-badutf8.args", // passing args via a file
"tests/ui/commandline-argfile.args", // passing args via a file "tests/ui/argfile/commandline-argfile.args", // passing args via a file
"tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib "tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib
"tests/ui/include-macros/data.bin", // testing including data with the include macros "tests/ui/include-macros/data.bin", // testing including data with the include macros
"tests/ui/include-macros/file.txt", // testing including data with the include macros "tests/ui/include-macros/file.txt", // testing including data with the include macros

View file

@ -0,0 +1,17 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. This test uses backslash as the path separator for the command
// line arguments and is only run on windows.
//
//@ only-windows
//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-badutf8.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,2 @@
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args

View file

@ -0,0 +1,18 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. We have a duplicated version of this test that uses backslash as
// the path separator for the command line arguments that is only run on
// windows.
//
//@ ignore-windows
//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-badutf8.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,2 @@
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args

View file

@ -1,8 +1,13 @@
// Check to see if we can get parameters from an @argsfile file // Check to see if we can get parameters from an @argsfile file
// //
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. This test uses backslash as the path separator for the command
// line arguments and is only run on windows.
//
//@ only-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" //@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args
#[cfg(not(cmdline_set))] #[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set"); compile_error!("cmdline_set not set");

View file

@ -0,0 +1,2 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)

View file

@ -0,0 +1,20 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. We have a duplicated version of this test that uses backslash as
// the path separator for the command line arguments that is only run on
// windows.
//
//@ ignore-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,2 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)

View file

@ -0,0 +1,20 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. This test uses backslash as the path separator for the command
// line arguments and is only run on windows.
//
//@ only-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,6 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR)

View file

@ -0,0 +1,21 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. We have a duplicated version of this test that uses backslash as
// the path separator for the command line arguments that is only run on
// windows.
//
//@ ignore-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,6 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR)

View file

@ -1,7 +1,7 @@
// Check to see if we can get parameters from an @argsfile file // Check to see if we can get parameters from an @argsfile file
// //
//@ check-pass //@ check-pass
//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile.args
#[cfg(not(cmdline_set))] #[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set"); compile_error!("cmdline_set not set");

View file

@ -1,12 +0,0 @@
// Check to see if we can get parameters from an @argsfile file
//
//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -1,2 +0,0 @@
error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args

View file

@ -1,2 +0,0 @@
error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)

View file

@ -0,0 +1,17 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. This test uses backslash as the path separator for the command
// line arguments and is only run on windows.
//
//@ only-windows
//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-badutf8.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,2 @@
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args

View file

@ -0,0 +1,18 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. We have a duplicated version of this test that uses backslash as
// the path separator for the command line arguments that is only run on
// windows.
//
//@ ignore-windows
//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-badutf8.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,2 @@
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args

View file

@ -1,8 +1,13 @@
// Check to see if we can get parameters from an @argsfile file // Check to see if we can get parameters from an @argsfile file
// //
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. This test uses backslash as the path separator for the command
// line arguments and is only run on windows.
//
//@ only-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" //@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args
#[cfg(not(cmdline_set))] #[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set"); compile_error!("cmdline_set not set");

View file

@ -0,0 +1,2 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)

View file

@ -0,0 +1,20 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. We have a duplicated version of this test that uses backslash as
// the path separator for the command line arguments that is only run on
// windows.
//
//@ ignore-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,2 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)

View file

@ -0,0 +1,20 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. This test uses backslash as the path separator for the command
// line arguments and is only run on windows.
//
//@ only-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,6 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR)

View file

@ -0,0 +1,21 @@
// Check to see if we can get parameters from an @argsfile file
//
// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path
// separators. We have a duplicated version of this test that uses backslash as
// the path separator for the command line arguments that is only run on
// windows.
//
//@ ignore-windows
//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR"
//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING "
//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -0,0 +1,6 @@
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR)

View file

@ -1,7 +1,7 @@
// Check to see if we can get parameters from an @argsfile file // Check to see if we can get parameters from an @argsfile file
// //
//@ build-pass //@ build-pass
//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile.args
#[cfg(not(cmdline_set))] #[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set"); compile_error!("cmdline_set not set");

View file

@ -1,12 +0,0 @@
// Check to see if we can get parameters from an @argsfile file
//
//@ compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args
#[cfg(not(cmdline_set))]
compile_error!("cmdline_set not set");
#[cfg(not(unbroken))]
compile_error!("unbroken not set");
fn main() {
}

View file

@ -1,2 +0,0 @@
error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args

View file

@ -1,2 +0,0 @@
error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)

View file

@ -1,2 +1,2 @@
error: Failed to load argument file: Invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args error: failed to load argument file: invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args

View file

@ -1,2 +1,2 @@
error: Failed to load argument file: Invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args error: failed to load argument file: invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args