From 63091b105d08b7b0db19d699d3be3060acde04ad Mon Sep 17 00:00:00 2001
From: beetrees <b@beetr.ee>
Date: Mon, 15 May 2023 18:34:32 +0000
Subject: [PATCH] Make `arg_expand_all` not short-circuit on first error

---
 compiler/rustc_driver_impl/src/args.rs        | 27 ++++++++++++-------
 compiler/rustc_driver_impl/src/lib.rs         |  2 +-
 src/librustdoc/lib.rs                         |  2 +-
 src/tools/tidy/src/ui_tests.rs                |  6 ++---
 .../commandline-argfile-badutf8-windows.rs    | 17 ++++++++++++
 ...commandline-argfile-badutf8-windows.stderr |  2 ++
 .../commandline-argfile-badutf8.args          |  0
 .../argfile/commandline-argfile-badutf8.rs    | 18 +++++++++++++
 .../commandline-argfile-badutf8.stderr        |  2 ++
 .../commandline-argfile-missing-windows.rs}   |  7 ++++-
 ...commandline-argfile-missing-windows.stderr |  2 ++
 .../argfile/commandline-argfile-missing.rs    | 20 ++++++++++++++
 .../commandline-argfile-missing.stderr        |  2 ++
 .../commandline-argfile-multiple-windows.rs   | 20 ++++++++++++++
 ...ommandline-argfile-multiple-windows.stderr |  6 +++++
 .../argfile/commandline-argfile-multiple.rs   | 21 +++++++++++++++
 .../commandline-argfile-multiple.stderr       |  6 +++++
 .../{ => argfile}/commandline-argfile.args    |  0
 .../{ => argfile}/commandline-argfile.rs      |  2 +-
 .../rustdoc-ui/commandline-argfile-badutf8.rs | 12 ---------
 .../commandline-argfile-badutf8.stderr        |  2 --
 .../commandline-argfile-missing.stderr        |  2 --
 .../commandline-argfile-badutf8-windows.rs    | 17 ++++++++++++
 ...commandline-argfile-badutf8-windows.stderr |  2 ++
 .../commandline-argfile-badutf8.args          |  0
 .../ui/argfile/commandline-argfile-badutf8.rs | 18 +++++++++++++
 .../commandline-argfile-badutf8.stderr        |  2 ++
 .../commandline-argfile-missing-windows.rs}   |  7 ++++-
 ...commandline-argfile-missing-windows.stderr |  2 ++
 .../ui/argfile/commandline-argfile-missing.rs | 20 ++++++++++++++
 .../commandline-argfile-missing.stderr        |  2 ++
 .../commandline-argfile-multiple-windows.rs   | 20 ++++++++++++++
 ...ommandline-argfile-multiple-windows.stderr |  6 +++++
 .../argfile/commandline-argfile-multiple.rs   | 21 +++++++++++++++
 .../commandline-argfile-multiple.stderr       |  6 +++++
 .../ui/{ => argfile}/commandline-argfile.args |  0
 tests/ui/{ => argfile}/commandline-argfile.rs |  2 +-
 tests/ui/commandline-argfile-badutf8.rs       | 12 ---------
 tests/ui/commandline-argfile-badutf8.stderr   |  2 --
 tests/ui/commandline-argfile-missing.stderr   |  2 --
 .../shell-argfiles-badquotes-windows.stderr   |  2 +-
 .../shell-argfiles-badquotes.stderr           |  2 +-
 42 files changed, 270 insertions(+), 53 deletions(-)
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr
 rename tests/rustdoc-ui/{ => argfile}/commandline-argfile-badutf8.args (100%)
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr
 rename tests/{ui/commandline-argfile-missing.rs => rustdoc-ui/argfile/commandline-argfile-missing-windows.rs} (55%)
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-missing.rs
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs
 create mode 100644 tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr
 rename tests/rustdoc-ui/{ => argfile}/commandline-argfile.args (100%)
 rename tests/rustdoc-ui/{ => argfile}/commandline-argfile.rs (72%)
 delete mode 100644 tests/rustdoc-ui/commandline-argfile-badutf8.rs
 delete mode 100644 tests/rustdoc-ui/commandline-argfile-badutf8.stderr
 delete mode 100644 tests/rustdoc-ui/commandline-argfile-missing.stderr
 create mode 100644 tests/ui/argfile/commandline-argfile-badutf8-windows.rs
 create mode 100644 tests/ui/argfile/commandline-argfile-badutf8-windows.stderr
 rename tests/ui/{ => argfile}/commandline-argfile-badutf8.args (100%)
 create mode 100644 tests/ui/argfile/commandline-argfile-badutf8.rs
 create mode 100644 tests/ui/argfile/commandline-argfile-badutf8.stderr
 rename tests/{rustdoc-ui/commandline-argfile-missing.rs => ui/argfile/commandline-argfile-missing-windows.rs} (55%)
 create mode 100644 tests/ui/argfile/commandline-argfile-missing-windows.stderr
 create mode 100644 tests/ui/argfile/commandline-argfile-missing.rs
 create mode 100644 tests/ui/argfile/commandline-argfile-missing.stderr
 create mode 100644 tests/ui/argfile/commandline-argfile-multiple-windows.rs
 create mode 100644 tests/ui/argfile/commandline-argfile-multiple-windows.stderr
 create mode 100644 tests/ui/argfile/commandline-argfile-multiple.rs
 create mode 100644 tests/ui/argfile/commandline-argfile-multiple.stderr
 rename tests/ui/{ => argfile}/commandline-argfile.args (100%)
 rename tests/ui/{ => argfile}/commandline-argfile.rs (72%)
 delete mode 100644 tests/ui/commandline-argfile-badutf8.rs
 delete mode 100644 tests/ui/commandline-argfile-badutf8.stderr
 delete mode 100644 tests/ui/commandline-argfile-missing.stderr

diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs
index 8b6fb5fd660..8c03f54bb59 100644
--- a/compiler/rustc_driver_impl/src/args.rs
+++ b/compiler/rustc_driver_impl/src/args.rs
@@ -4,6 +4,7 @@ use std::fs;
 use std::io;
 
 use rustc_session::EarlyDiagCtxt;
+use rustc_span::ErrorGuaranteed;
 
 /// Expands argfiles in command line arguments.
 #[derive(Default)]
@@ -86,7 +87,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 +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.
 /// 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())
 }
 
 #[derive(Debug)]
-pub enum Error {
-    Utf8Error(Option<String>),
+enum Error {
+    Utf8Error(String),
     IOError(String, io::Error),
     ShellParseError(String),
 }
@@ -118,10 +126,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 3b6bf0005a3..3831bbc1e15 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(()) };
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 33837fe5652..faa92c9d15a 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -705,7 +705,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/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index a9c5be913ba..b4540f14627 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
similarity index 100%
rename from tests/rustdoc-ui/commandline-argfile-badutf8.args
rename to 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
similarity index 55%
rename from tests/ui/commandline-argfile-missing.rs
rename to 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
similarity index 100%
rename from tests/rustdoc-ui/commandline-argfile.args
rename to tests/rustdoc-ui/argfile/commandline-argfile.args
diff --git a/tests/rustdoc-ui/commandline-argfile.rs b/tests/rustdoc-ui/argfile/commandline-argfile.rs
similarity index 72%
rename from tests/rustdoc-ui/commandline-argfile.rs
rename to 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
similarity index 100%
rename from tests/ui/commandline-argfile-badutf8.args
rename to 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
similarity index 55%
rename from tests/rustdoc-ui/commandline-argfile-missing.rs
rename to 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
similarity index 100%
rename from tests/ui/commandline-argfile.args
rename to tests/ui/argfile/commandline-argfile.args
diff --git a/tests/ui/commandline-argfile.rs b/tests/ui/argfile/commandline-argfile.rs
similarity index 72%
rename from tests/ui/commandline-argfile.rs
rename to 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