about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_driver_impl/src/args.rs55
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs12
-rw-r--r--src/librustdoc/lib.rs15
-rw-r--r--src/tools/clippy/src/driver.rs2
-rw-r--r--src/tools/miri/src/bin/miri.rs6
-rw-r--r--src/tools/tidy/src/ui_tests.rs6
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs17
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr2
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args (renamed from tests/rustdoc-ui/commandline-argfile-badutf8.args)0
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs18
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr2
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs (renamed from tests/ui/commandline-argfile-missing.rs)7
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr2
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-missing.rs20
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr2
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs20
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr6
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs21
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr6
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile.args (renamed from tests/rustdoc-ui/commandline-argfile.args)0
-rw-r--r--tests/rustdoc-ui/argfile/commandline-argfile.rs (renamed from tests/rustdoc-ui/commandline-argfile.rs)2
-rw-r--r--tests/rustdoc-ui/commandline-argfile-badutf8.rs12
-rw-r--r--tests/rustdoc-ui/commandline-argfile-badutf8.stderr2
-rw-r--r--tests/rustdoc-ui/commandline-argfile-missing.stderr2
-rw-r--r--tests/ui/argfile/commandline-argfile-badutf8-windows.rs17
-rw-r--r--tests/ui/argfile/commandline-argfile-badutf8-windows.stderr2
-rw-r--r--tests/ui/argfile/commandline-argfile-badutf8.args (renamed from tests/ui/commandline-argfile-badutf8.args)0
-rw-r--r--tests/ui/argfile/commandline-argfile-badutf8.rs18
-rw-r--r--tests/ui/argfile/commandline-argfile-badutf8.stderr2
-rw-r--r--tests/ui/argfile/commandline-argfile-missing-windows.rs (renamed from tests/rustdoc-ui/commandline-argfile-missing.rs)7
-rw-r--r--tests/ui/argfile/commandline-argfile-missing-windows.stderr2
-rw-r--r--tests/ui/argfile/commandline-argfile-missing.rs20
-rw-r--r--tests/ui/argfile/commandline-argfile-missing.stderr2
-rw-r--r--tests/ui/argfile/commandline-argfile-multiple-windows.rs20
-rw-r--r--tests/ui/argfile/commandline-argfile-multiple-windows.stderr6
-rw-r--r--tests/ui/argfile/commandline-argfile-multiple.rs21
-rw-r--r--tests/ui/argfile/commandline-argfile-multiple.stderr6
-rw-r--r--tests/ui/argfile/commandline-argfile.args (renamed from tests/ui/commandline-argfile.args)0
-rw-r--r--tests/ui/argfile/commandline-argfile.rs (renamed from tests/ui/commandline-argfile.rs)2
-rw-r--r--tests/ui/commandline-argfile-badutf8.rs12
-rw-r--r--tests/ui/commandline-argfile-badutf8.stderr2
-rw-r--r--tests/ui/commandline-argfile-missing.stderr2
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr2
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr2
44 files changed, 303 insertions, 79 deletions
diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs
index 8b6fb5fd660..28574457389 100644
--- a/compiler/rustc_driver_impl/src/args.rs
+++ b/compiler/rustc_driver_impl/src/args.rs
@@ -1,9 +1,7 @@
-use std::error;
-use std::fmt;
-use std::fs;
-use std::io;
+use std::{env, error, fmt, fs, io};
 
 use rustc_session::EarlyDiagCtxt;
+use rustc_span::ErrorGuaranteed;
 
 /// Expands argfiles in command line arguments.
 #[derive(Default)]
@@ -86,7 +84,7 @@ impl Expander {
     fn read_file(path: &str) -> Result<String, Error> {
         fs::read_to_string(path).map_err(|e| {
             if e.kind() == io::ErrorKind::InvalidData {
-                Error::Utf8Error(Some(path.to_string()))
+                Error::Utf8Error(path.to_string())
             } else {
                 Error::IOError(path.to_string(), e)
             }
@@ -94,23 +92,53 @@ 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.
 /// If this function is intended to be used with command line arguments,
 /// `argv[0]` must be removed prior to calling it manually.
 #[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 result = Ok(());
     for arg in at_args {
         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())
+}
+
+/// Gets the raw unprocessed command-line arguments as Unicode strings, without doing any further
+/// processing (e.g., without `@file` expansion).
+///
+/// This function is identical to [`env::args()`] except that it emits an error when it encounters
+/// non-Unicode arguments instead of panicking.
+pub fn raw_args(early_dcx: &EarlyDiagCtxt) -> Result<Vec<String>, ErrorGuaranteed> {
+    let mut res = Ok(Vec::new());
+    for (i, arg) in env::args_os().enumerate() {
+        match arg.into_string() {
+            Ok(arg) => {
+                if let Ok(args) = &mut res {
+                    args.push(arg);
+                }
+            }
+            Err(arg) => {
+                res =
+                    Err(early_dcx.early_err(format!("argument {i} is not valid Unicode: {arg:?}")))
+            }
+        }
+    }
+    res
 }
 
 #[derive(Debug)]
-pub enum Error {
-    Utf8Error(Option<String>),
+enum Error {
+    Utf8Error(String),
     IOError(String, io::Error),
     ShellParseError(String),
 }
@@ -118,10 +146,9 @@ pub enum Error {
 impl fmt::Display for Error {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            Error::Utf8Error(None) => write!(fmt, "Utf8 error"),
-            Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {path}"),
-            Error::IOError(path, err) => write!(fmt, "IO Error: {path}: {err}"),
-            Error::ShellParseError(path) => write!(fmt, "Invalid shell-style arguments in {path}"),
+            Error::Utf8Error(path) => write!(fmt, "UTF-8 error in {path}"),
+            Error::IOError(path, err) => write!(fmt, "IO error: {path}: {err}"),
+            Error::ShellParseError(path) => write!(fmt, "invalid shell-style arguments in {path}"),
         }
     }
 }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 89ab5c6bd3b..e06d1d245b2 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -292,7 +292,7 @@ fn run_compiler(
     // the compiler with @empty_file as argv[0] and no more arguments.
     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(()) };
 
@@ -1515,15 +1515,7 @@ pub fn main() -> ! {
     let mut callbacks = TimePassesCallbacks::default();
     let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
     let exit_code = catch_with_exit_code(|| {
-        let args = env::args_os()
-            .enumerate()
-            .map(|(i, arg)| {
-                arg.into_string().unwrap_or_else(|arg| {
-                    early_dcx.early_fatal(format!("argument {i} is not valid Unicode: {arg:?}"))
-                })
-            })
-            .collect::<Vec<_>>();
-        RunCompiler::new(&args, &mut callbacks)
+        RunCompiler::new(&args::raw_args(&early_dcx)?, &mut callbacks)
             .set_using_internal_features(using_internal_features)
             .run()
     });
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 33837fe5652..39d27b104cd 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -179,21 +179,14 @@ pub fn main() {
     rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG"));
 
     let exit_code = rustc_driver::catch_with_exit_code(|| {
-        let args = env::args_os()
-            .enumerate()
-            .map(|(i, arg)| {
-                arg.into_string().unwrap_or_else(|arg| {
-                    early_dcx.early_fatal(format!("argument {i} is not valid Unicode: {arg:?}"))
-                })
-            })
-            .collect::<Vec<_>>();
-        main_args(&mut early_dcx, &args, using_internal_features)
+        let at_args = rustc_driver::args::raw_args(&early_dcx)?;
+        main_args(&mut early_dcx, &at_args, using_internal_features)
     });
     process::exit(exit_code);
 }
 
 fn init_logging(early_dcx: &EarlyDiagCtxt) {
-    let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() {
+    let color_logs = match env::var("RUSTDOC_LOG_COLOR").as_deref() {
         Ok("always") => true,
         Ok("never") => false,
         Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
@@ -705,7 +698,7 @@ fn main_args(
     // the compiler with @empty_file as argv[0] and no more arguments.
     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();
     for option in opts() {
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 8fc66644632..9e42abbc9aa 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -190,7 +190,7 @@ pub fn main() {
     });
 
     exit(rustc_driver::catch_with_exit_code(move || {
-        let mut orig_args: Vec<String> = env::args().collect();
+        let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?;
 
         let has_sysroot_arg = |args: &mut [String]| -> bool {
             if arg_value(args, "--sysroot", |_| true).is_some() {
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 2f37a64576e..a9b5aa5f1ef 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -342,6 +342,8 @@ fn main() {
     // (`install_ice_hook` might change `RUST_BACKTRACE`.)
     let env_snapshot = env::vars_os().collect::<Vec<_>>();
 
+    let args = rustc_driver::args::raw_args(&early_dcx).unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE));
+
     // If the environment asks us to actually be rustc, then do that.
     if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
         // Earliest rustc setup.
@@ -359,7 +361,7 @@ fn main() {
 
         // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments.
         run_compiler(
-            env::args().collect(),
+            args,
             target_crate,
             &mut MiriBeRustCompilerCalls { target_crate },
             using_internal_features,
@@ -382,7 +384,7 @@ fn main() {
 
     // If user has explicitly enabled/disabled isolation
     let mut isolation_enabled: Option<bool> = None;
-    for arg in env::args() {
+    for arg in args {
         if rustc_args.is_empty() {
             // Very first arg: binary name.
             rustc_args.push(arg);
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 1a53637ad42..b4ccddda0d8 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -18,7 +18,7 @@ const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 
 const ISSUES_ENTRY_LIMIT: usize = 1750;
-const ROOT_ENTRY_LIMIT: usize = 872;
+const ROOT_ENTRY_LIMIT: usize = 866;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "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/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/commandline-argfile-badutf8.args",    // passing args via a file
-    "tests/ui/commandline-argfile.args",            // passing args via a file
+    "tests/ui/argfile/commandline-argfile-badutf8.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/include-macros/data.bin", // testing including data with the include macros
     "tests/ui/include-macros/file.txt", // testing including data with the include macros
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs
new file mode 100644
index 00000000000..eba17ca6f7e
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs
@@ -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() {
+}
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr
new file mode 100644
index 00000000000..b4c0d4c20d7
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
+
diff --git a/tests/rustdoc-ui/commandline-argfile-badutf8.args b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args
index c070b0c2400..c070b0c2400 100644
--- a/tests/rustdoc-ui/commandline-argfile-badutf8.args
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs
new file mode 100644
index 00000000000..1b2e52af762
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs
@@ -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() {
+}
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr
new file mode 100644
index 00000000000..b4c0d4c20d7
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
+
diff --git a/tests/ui/commandline-argfile-missing.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs
index bb9644d66ce..24cfd25ccad 100644
--- a/tests/ui/commandline-argfile-missing.rs
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs
@@ -1,8 +1,13 @@
 // 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 "
-//@ 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))]
 compile_error!("cmdline_set not set");
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr
new file mode 100644
index 00000000000..28a20debf1c
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
+
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs
new file mode 100644
index 00000000000..fe6a849b0c8
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs
@@ -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() {
+}
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr
new file mode 100644
index 00000000000..28a20debf1c
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
+
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs
new file mode 100644
index 00000000000..84c050d84e2
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs
@@ -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() {
+}
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr
new file mode 100644
index 00000000000..ad3b445c958
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr
@@ -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)
+
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs
new file mode 100644
index 00000000000..f658ee34fbb
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs
@@ -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() {
+}
diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr
new file mode 100644
index 00000000000..ad3b445c958
--- /dev/null
+++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr
@@ -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)
+
diff --git a/tests/rustdoc-ui/commandline-argfile.args b/tests/rustdoc-ui/argfile/commandline-argfile.args
index 972938bf6c8..972938bf6c8 100644
--- a/tests/rustdoc-ui/commandline-argfile.args
+++ b/tests/rustdoc-ui/argfile/commandline-argfile.args
diff --git a/tests/rustdoc-ui/commandline-argfile.rs b/tests/rustdoc-ui/argfile/commandline-argfile.rs
index d71bc72562b..b0b314f53ce 100644
--- a/tests/rustdoc-ui/commandline-argfile.rs
+++ b/tests/rustdoc-ui/argfile/commandline-argfile.rs
@@ -1,7 +1,7 @@
 // Check to see if we can get parameters from an @argsfile file
 //
 //@ 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))]
 compile_error!("cmdline_set not set");
diff --git a/tests/rustdoc-ui/commandline-argfile-badutf8.rs b/tests/rustdoc-ui/commandline-argfile-badutf8.rs
deleted file mode 100644
index b3a19fa6274..00000000000
--- a/tests/rustdoc-ui/commandline-argfile-badutf8.rs
+++ /dev/null
@@ -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() {
-}
diff --git a/tests/rustdoc-ui/commandline-argfile-badutf8.stderr b/tests/rustdoc-ui/commandline-argfile-badutf8.stderr
deleted file mode 100644
index 9af6fc0a518..00000000000
--- a/tests/rustdoc-ui/commandline-argfile-badutf8.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args
-
diff --git a/tests/rustdoc-ui/commandline-argfile-missing.stderr b/tests/rustdoc-ui/commandline-argfile-missing.stderr
deleted file mode 100644
index 179ad831004..00000000000
--- a/tests/rustdoc-ui/commandline-argfile-missing.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
-
diff --git a/tests/ui/argfile/commandline-argfile-badutf8-windows.rs b/tests/ui/argfile/commandline-argfile-badutf8-windows.rs
new file mode 100644
index 00000000000..eba17ca6f7e
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-badutf8-windows.rs
@@ -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() {
+}
diff --git a/tests/ui/argfile/commandline-argfile-badutf8-windows.stderr b/tests/ui/argfile/commandline-argfile-badutf8-windows.stderr
new file mode 100644
index 00000000000..b4c0d4c20d7
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-badutf8-windows.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
+
diff --git a/tests/ui/commandline-argfile-badutf8.args b/tests/ui/argfile/commandline-argfile-badutf8.args
index c070b0c2400..c070b0c2400 100644
--- a/tests/ui/commandline-argfile-badutf8.args
+++ b/tests/ui/argfile/commandline-argfile-badutf8.args
diff --git a/tests/ui/argfile/commandline-argfile-badutf8.rs b/tests/ui/argfile/commandline-argfile-badutf8.rs
new file mode 100644
index 00000000000..1b2e52af762
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-badutf8.rs
@@ -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() {
+}
diff --git a/tests/ui/argfile/commandline-argfile-badutf8.stderr b/tests/ui/argfile/commandline-argfile-badutf8.stderr
new file mode 100644
index 00000000000..b4c0d4c20d7
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-badutf8.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args
+
diff --git a/tests/rustdoc-ui/commandline-argfile-missing.rs b/tests/ui/argfile/commandline-argfile-missing-windows.rs
index bb9644d66ce..24cfd25ccad 100644
--- a/tests/rustdoc-ui/commandline-argfile-missing.rs
+++ b/tests/ui/argfile/commandline-argfile-missing-windows.rs
@@ -1,8 +1,13 @@
 // 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 "
-//@ 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))]
 compile_error!("cmdline_set not set");
diff --git a/tests/ui/argfile/commandline-argfile-missing-windows.stderr b/tests/ui/argfile/commandline-argfile-missing-windows.stderr
new file mode 100644
index 00000000000..28a20debf1c
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-missing-windows.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
+
diff --git a/tests/ui/argfile/commandline-argfile-missing.rs b/tests/ui/argfile/commandline-argfile-missing.rs
new file mode 100644
index 00000000000..fe6a849b0c8
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-missing.rs
@@ -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() {
+}
diff --git a/tests/ui/argfile/commandline-argfile-missing.stderr b/tests/ui/argfile/commandline-argfile-missing.stderr
new file mode 100644
index 00000000000..28a20debf1c
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-missing.stderr
@@ -0,0 +1,2 @@
+error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
+
diff --git a/tests/ui/argfile/commandline-argfile-multiple-windows.rs b/tests/ui/argfile/commandline-argfile-multiple-windows.rs
new file mode 100644
index 00000000000..84c050d84e2
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-multiple-windows.rs
@@ -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() {
+}
diff --git a/tests/ui/argfile/commandline-argfile-multiple-windows.stderr b/tests/ui/argfile/commandline-argfile-multiple-windows.stderr
new file mode 100644
index 00000000000..ad3b445c958
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-multiple-windows.stderr
@@ -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)
+
diff --git a/tests/ui/argfile/commandline-argfile-multiple.rs b/tests/ui/argfile/commandline-argfile-multiple.rs
new file mode 100644
index 00000000000..f658ee34fbb
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-multiple.rs
@@ -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() {
+}
diff --git a/tests/ui/argfile/commandline-argfile-multiple.stderr b/tests/ui/argfile/commandline-argfile-multiple.stderr
new file mode 100644
index 00000000000..ad3b445c958
--- /dev/null
+++ b/tests/ui/argfile/commandline-argfile-multiple.stderr
@@ -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)
+
diff --git a/tests/ui/commandline-argfile.args b/tests/ui/argfile/commandline-argfile.args
index 972938bf6c8..972938bf6c8 100644
--- a/tests/ui/commandline-argfile.args
+++ b/tests/ui/argfile/commandline-argfile.args
diff --git a/tests/ui/commandline-argfile.rs b/tests/ui/argfile/commandline-argfile.rs
index 8577312a3c4..387a8d033b3 100644
--- a/tests/ui/commandline-argfile.rs
+++ b/tests/ui/argfile/commandline-argfile.rs
@@ -1,7 +1,7 @@
 // Check to see if we can get parameters from an @argsfile file
 //
 //@ 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))]
 compile_error!("cmdline_set not set");
diff --git a/tests/ui/commandline-argfile-badutf8.rs b/tests/ui/commandline-argfile-badutf8.rs
deleted file mode 100644
index b3a19fa6274..00000000000
--- a/tests/ui/commandline-argfile-badutf8.rs
+++ /dev/null
@@ -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() {
-}
diff --git a/tests/ui/commandline-argfile-badutf8.stderr b/tests/ui/commandline-argfile-badutf8.stderr
deleted file mode 100644
index 9af6fc0a518..00000000000
--- a/tests/ui/commandline-argfile-badutf8.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args
-
diff --git a/tests/ui/commandline-argfile-missing.stderr b/tests/ui/commandline-argfile-missing.stderr
deleted file mode 100644
index 179ad831004..00000000000
--- a/tests/ui/commandline-argfile-missing.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
-
diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr
index 14adb1f740a..dc219c153f7 100644
--- a/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr
+++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr
@@ -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
 
diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr b/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
index 14adb1f740a..dc219c153f7 100644
--- a/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
+++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
@@ -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