about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-09 17:19:52 +0000
committerbors <bors@rust-lang.org>2024-01-09 17:19:52 +0000
commitae9d24de80b00b4158d1a29a212a6b02aeda0e75 (patch)
treeea43a15bdb935ec4dc1be01f02a9c77e19d35b6c
parent5876c8cdfd3df742c334d6447d44d760c77103b6 (diff)
parentd61b92f154aa9fadfc28fd9cb0753f7efda5918b (diff)
downloadrust-ae9d24de80b00b4158d1a29a212a6b02aeda0e75.tar.gz
rust-ae9d24de80b00b4158d1a29a212a6b02aeda0e75.zip
Auto merge of #119777 - GuillaumeGomez:rollup-mf82vow, r=GuillaumeGomez
Rollup of 5 pull requests

Successful merges:

 - #118241 (Making `User<T>` and `User<[T]>` `Send`)
 - #118645 (chore: Bump compiler_builtins)
 - #118680 (Add support for shell argfiles)
 - #119721 (`~const` trait and projection bounds do not imply their non-const counterparts)
 - #119768 (core: panic: fix broken link)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock5
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml1
-rw-r--r--compiler/rustc_driver_impl/src/args.rs107
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs38
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--library/core/src/macros/panic.md2
-rw-r--r--library/std/Cargo.toml6
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/alloc.rs6
-rw-r--r--src/doc/unstable-book/src/compiler-flags/shell-argfiles.md11
-rw-r--r--src/tools/tidy/src/deps.rs1
-rw-r--r--src/tools/tidy/src/ui_tests.rs6
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr16
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs86
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr21
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs17
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs9
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr65
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr34
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr10
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.rs11
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr2
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-badquotes.args1
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-badquotes.rs12
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr2
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args1
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-via-argfile.args1
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles-via-argfile.rs10
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles.args3
-rw-r--r--tests/ui/shell-argfiles/shell-argfiles.rs19
35 files changed, 414 insertions, 151 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5b9dd05398f..75c7de4f405 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -704,9 +704,9 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.103"
+version = "0.1.104"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3b73c3443a5fd2438d7ba4853c64e4c8efc2404a9e28a9234cc2d5eebc6c242"
+checksum = "99c3f9035afc33f4358773239573f7d121099856753e1bbd2a6a5207098fc741"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
@@ -3738,6 +3738,7 @@ dependencies = [
  "rustc_trait_selection",
  "rustc_ty_utils",
  "serde_json",
+ "shlex",
  "time",
  "tracing",
  "windows",
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 49042984553..97a7dfef3b3 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -50,6 +50,7 @@ rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
 serde_json = "1.0.59"
+shlex = "1.0"
 time = { version = "0.3", default-features = false, features = ["alloc", "formatting"] }
 tracing = { version = "0.1.35" }
 # tidy-alphabetical-end
diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs
index b7407f5a508..5dfd37a6da4 100644
--- a/compiler/rustc_driver_impl/src/args.rs
+++ b/compiler/rustc_driver_impl/src/args.rs
@@ -5,18 +5,92 @@ use std::io;
 
 use rustc_session::EarlyDiagCtxt;
 
-fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
-    if let Some(path) = arg.strip_prefix('@') {
-        let file = match fs::read_to_string(path) {
-            Ok(file) => file,
-            Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
-                return Err(Error::Utf8Error(Some(path.to_string())));
+/// Expands argfiles in command line arguments.
+#[derive(Default)]
+struct Expander {
+    shell_argfiles: bool,
+    next_is_unstable_option: bool,
+    expanded: Vec<String>,
+}
+
+impl Expander {
+    /// Handles the next argument. If the argument is an argfile, it is expanded
+    /// inline.
+    fn arg(&mut self, arg: &str) -> Result<(), Error> {
+        if let Some(argfile) = arg.strip_prefix('@') {
+            match argfile.split_once(':') {
+                Some(("shell", path)) if self.shell_argfiles => {
+                    shlex::split(&Self::read_file(path)?)
+                        .ok_or_else(|| Error::ShellParseError(path.to_string()))?
+                        .into_iter()
+                        .for_each(|arg| self.push(arg));
+                }
+                _ => {
+                    let contents = Self::read_file(argfile)?;
+                    contents.lines().for_each(|arg| self.push(arg.to_string()));
+                }
+            }
+        } else {
+            self.push(arg.to_string());
+        }
+
+        Ok(())
+    }
+
+    /// Adds a command line argument verbatim with no argfile expansion.
+    fn push(&mut self, arg: String) {
+        // Unfortunately, we have to do some eager argparsing to handle unstable
+        // options which change the behavior of argfile arguments.
+        //
+        // Normally, all of the argfile arguments (e.g. `@args.txt`) are
+        // expanded into our arguments list *and then* the whole list of
+        // arguments are passed on to be parsed. However, argfile parsing
+        // options like `-Zshell_argfiles` need to change the behavior of that
+        // argument expansion. So we have to do a little parsing on our own here
+        // instead of leaning on the existing logic.
+        //
+        // All we care about are unstable options, so we parse those out and
+        // look for any that affect how we expand argfiles. This argument
+        // inspection is very conservative; we only change behavior when we see
+        // exactly the options we're looking for and everything gets passed
+        // through.
+
+        if self.next_is_unstable_option {
+            self.inspect_unstable_option(&arg);
+            self.next_is_unstable_option = false;
+        } else if let Some(unstable_option) = arg.strip_prefix("-Z") {
+            if unstable_option.is_empty() {
+                self.next_is_unstable_option = true;
+            } else {
+                self.inspect_unstable_option(unstable_option);
+            }
+        }
+
+        self.expanded.push(arg);
+    }
+
+    /// Consumes the `Expander`, returning the expanded arguments.
+    fn finish(self) -> Vec<String> {
+        self.expanded
+    }
+
+    /// Parses any relevant unstable flags specified on the command line.
+    fn inspect_unstable_option(&mut self, option: &str) {
+        match option {
+            "shell-argfiles" => self.shell_argfiles = true,
+            _ => (),
+        }
+    }
+
+    /// Reads the contents of a file as UTF-8.
+    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()))
+            } else {
+                Error::IOError(path.to_string(), e)
             }
-            Err(err) => return Err(Error::IOError(path.to_string(), err)),
-        };
-        Ok(file.lines().map(ToString::to_string).collect())
-    } else {
-        Ok(vec![arg])
+        })
     }
 }
 
@@ -24,20 +98,20 @@ fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
 /// If this function is intended to be used with command line arguments,
 /// `argv[0]` must be removed prior to calling it manually.
 pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<String> {
-    let mut args = Vec::new();
+    let mut expander = Expander::default();
     for arg in at_args {
-        match arg_expand(arg.clone()) {
-            Ok(arg) => args.extend(arg),
-            Err(err) => early_dcx.early_fatal(format!("Failed to load argument file: {err}")),
+        if let Err(err) = expander.arg(arg) {
+            early_dcx.early_fatal(format!("Failed to load argument file: {err}"));
         }
     }
-    args
+    expander.finish()
 }
 
 #[derive(Debug)]
 pub enum Error {
     Utf8Error(Option<String>),
     IOError(String, io::Error),
+    ShellParseError(String),
 }
 
 impl fmt::Display for Error {
@@ -46,6 +120,7 @@ impl fmt::Display for Error {
             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}"),
         }
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index eb6a5cc5b21..cdfb4c6389e 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1032,7 +1032,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             self.trait_defines_associated_item_named(r.def_id(), assoc_kind, assoc_name)
         });
 
-        let Some(mut bound) = matching_candidates.next() else {
+        let Some(bound) = matching_candidates.next() else {
             let reported = self.complain_about_assoc_item_not_found(
                 all_candidates,
                 &ty_param_name.to_string(),
@@ -1046,38 +1046,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         };
         debug!(?bound);
 
-        // look for a candidate that is not the same as our first bound, disregarding
-        // whether the bound is const.
-        let mut next_cand = matching_candidates.next();
-        while let Some(mut bound2) = next_cand {
-            debug!(?bound2);
-            if bound2.bound_vars() != bound.bound_vars() {
-                break;
-            }
-
-            let generics = tcx.generics_of(bound.def_id());
-            let Some(host_index) = generics.host_effect_index else { break };
-
-            // always return the bound that contains the host param.
-            if let ty::ConstKind::Param(_) = bound2.skip_binder().args.const_at(host_index).kind() {
-                (bound, bound2) = (bound2, bound);
-            }
-
-            let unconsted_args = bound
-                .skip_binder()
-                .args
-                .iter()
-                .enumerate()
-                .map(|(n, arg)| if host_index == n { tcx.consts.true_.into() } else { arg });
-
-            if unconsted_args.eq(bound2.skip_binder().args.iter()) {
-                next_cand = matching_candidates.next();
-            } else {
-                break;
-            }
-        }
-
-        if let Some(bound2) = next_cand {
+        if let Some(bound2) = matching_candidates.next() {
             debug!(?bound2);
 
             let assoc_kind_str = assoc_kind_str(assoc_kind);
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index b6688e0ce29..b69f679880d 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -45,24 +45,6 @@ impl<'tcx> Bounds<'tcx> {
         polarity: ty::ImplPolarity,
     ) {
         self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
-
-        // push a non-const (`host = true`) version of the bound if it is `~const`.
-        if tcx.features().effects
-            && let Some(host_effect_idx) = tcx.generics_of(trait_ref.def_id()).host_effect_index
-            && trait_ref.skip_binder().args.const_at(host_effect_idx) != tcx.consts.true_
-        {
-            let generics = tcx.generics_of(trait_ref.def_id());
-            let Some(host_index) = generics.host_effect_index else { return };
-            let trait_ref = trait_ref.map_bound(|mut trait_ref| {
-                trait_ref.args =
-                    tcx.mk_args_from_iter(trait_ref.args.iter().enumerate().map(|(n, arg)| {
-                        if host_index == n { tcx.consts.true_.into() } else { arg }
-                    }));
-                trait_ref
-            });
-
-            self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
-        }
     }
 
     fn push_trait_bound_inner(
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 41520718aa8..ab9ed6ef98d 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -11,7 +11,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate};
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span, DUMMY_SP};
+use rustc_span::{Span, DUMMY_SP};
 
 /// Returns a list of all type predicates (explicit and implicit) for the definition with
 /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
@@ -38,38 +38,12 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
         // an obligation and instead be skipped. Otherwise we'd use
         // `tcx.def_span(def_id);`
         let span = rustc_span::DUMMY_SP;
-        let non_const_bound = if tcx.features().effects && tcx.has_attr(def_id, sym::const_trait) {
-            // when `Self` is a const trait, also add `Self: Trait<.., true>` as implied bound,
-            // because only implementing `Self: Trait<.., false>` is currently not possible.
-            Some((
-                ty::TraitRef::new(
-                    tcx,
-                    def_id,
-                    ty::GenericArgs::for_item(tcx, def_id, |param, _| {
-                        if param.is_host_effect() {
-                            tcx.consts.true_.into()
-                        } else {
-                            tcx.mk_param_from_def(param)
-                        }
-                    }),
-                )
-                .to_predicate(tcx),
+
+        result.predicates =
+            tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
+                ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
                 span,
-            ))
-        } else {
-            None
-        };
-        result.predicates = tcx.arena.alloc_from_iter(
-            result
-                .predicates
-                .iter()
-                .copied()
-                .chain(std::iter::once((
-                    ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
-                    span,
-                )))
-                .chain(non_const_bound),
-        );
+            ))));
     }
     debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
     result
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 444e3700cf7..588139a303c 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -698,6 +698,7 @@ fn test_unstable_options_tracking_hash() {
     untracked!(query_dep_graph, true);
     untracked!(self_profile, SwitchWithOptPath::Enabled(None));
     untracked!(self_profile_events, Some(vec![String::new()]));
+    untracked!(shell_argfiles, true);
     untracked!(span_debug, true);
     untracked!(span_free_formats, true);
     untracked!(temps_dir, Some(String::from("abc")));
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 772c6df2e2d..c97b18ebd66 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1841,6 +1841,8 @@ written to standard error output)"),
                      query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"),
     share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "make the current crate share its generic instantiations"),
+    shell_argfiles: bool = (false, parse_bool, [UNTRACKED],
+        "allow argument files to be specified with POSIX \"shell-style\" argument quoting"),
     show_span: Option<String> = (None, parse_opt_string, [TRACKED],
         "show spans for compiler debugging (expr|pat|ty)"),
     simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md
index 60100c2655a..6bd23b3072e 100644
--- a/library/core/src/macros/panic.md
+++ b/library/core/src/macros/panic.md
@@ -56,7 +56,7 @@ For more detailed information about error handling check out the [book] or the
 [`panic_any`]: ../std/panic/fn.panic_any.html
 [`Box`]: ../std/boxed/struct.Box.html
 [`Any`]: crate::any::Any
-[`format!` syntax]: ../std/fmt/index.html
+[formatting syntax]: ../std/fmt/index.html
 [book]: ../book/ch09-00-error-handling.html
 [`std::result`]: ../std/result/index.html
 
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index fe66788b564..5dbfe4aa2ac 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
 libc = { version = "0.2.150", default-features = false, features = ['rustc-dep-of-std'], public = true }
-compiler_builtins = { version = "0.1.103" }
+compiler_builtins = { version = "0.1.104" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] }
@@ -54,8 +54,8 @@ hermit-abi = { version = "0.3.2", features = ['rustc-dep-of-std'], public = true
 wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
 
 [target.'cfg(target_os = "uefi")'.dependencies]
-r-efi = { version = "4.2.0", features = ['rustc-dep-of-std']}
-r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std']}
+r-efi = { version = "4.2.0", features = ['rustc-dep-of-std'] }
+r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] }
 
 [features]
 backtrace = [
diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
index 817c33b6603..f99cea360f1 100644
--- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
@@ -185,6 +185,12 @@ pub struct UserRef<T: ?Sized>(UnsafeCell<T>);
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub struct User<T: UserSafe + ?Sized>(NonNull<UserRef<T>>);
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T: UserSafeSized> Send for User<T> {}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T: UserSafeSized> Send for User<[T]> {}
+
 trait NewUserRef<T: ?Sized> {
     unsafe fn new_userref(v: T) -> Self;
 }
diff --git a/src/doc/unstable-book/src/compiler-flags/shell-argfiles.md b/src/doc/unstable-book/src/compiler-flags/shell-argfiles.md
new file mode 100644
index 00000000000..4f3c780972d
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/shell-argfiles.md
@@ -0,0 +1,11 @@
+# `shell-argfiles`
+
+--------------------
+
+The `-Zshell-argfiles` compiler flag allows argfiles to be parsed using POSIX
+"shell-style" quoting. When enabled, the compiler will use `shlex` to parse the
+arguments from argfiles specified with `@shell:<path>`.
+
+Because this feature controls the parsing of input arguments, the
+`-Zshell-argfiles` flag must be present before the argument specifying the
+shell-style arguemnt file.
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 3c00027b9fd..62d48315d43 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -325,6 +325,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "sha1",
     "sha2",
     "sharded-slab",
+    "shlex",
     "smallvec",
     "snap",
     "stable_deref_trait",
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 99c5dce347a..32e271d4a56 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 const ISSUES_ENTRY_LIMIT: usize = 1849;
-const ROOT_ENTRY_LIMIT: usize = 867;
+const ROOT_ENTRY_LIMIT: usize = 868;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
@@ -35,6 +35,10 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
     "tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
     "tests/ui/proc-macro/auxiliary/included-file.txt", // more include
     "tests/ui/invalid/foo.natvis.xml", // sample debugger visualizer
+    "tests/ui/shell-argfiles/shell-argfiles.args", // passing args via a file
+    "tests/ui/shell-argfiles/shell-argfiles-badquotes.args", // passing args via a file
+    "tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args", // passing args via a file
+    "tests/ui/shell-argfiles/shell-argfiles-via-argfile.args", // passing args via a file
 ];
 
 fn check_entries(tests_path: &Path, bad: &mut bool) {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs
index f41c1051fce..16b717bc181 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs
@@ -9,7 +9,7 @@ trait Foo {
 }
 
 const fn foo<T: ~const Foo>() {
-    <T as Foo>::Assoc::foo();
+    <T as /* FIXME: ~const */ Foo>::Assoc::foo();
 }
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
index 1b88839984f..268e337ee93 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
@@ -6,15 +6,17 @@ LL |     type Assoc: ~const Foo;
    |
    = note: this item cannot have `~const` trait bounds
 
-error[E0308]: mismatched types
-  --> $DIR/assoc-type-const-bound-usage.rs:12:5
+error[E0277]: the trait bound `T: Foo` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage.rs:12:6
    |
-LL |     <T as Foo>::Assoc::foo();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ expected `host`, found `true`
+LL |     <T as /* FIXME: ~const */ Foo>::Assoc::foo();
+   |      ^ the trait `Foo` is not implemented for `T`
    |
-   = note: expected constant `host`
-              found constant `true`
+help: consider further restricting this bound
+   |
+LL | const fn foo<T: ~const Foo + Foo>() {
+   |                            +++++
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs
new file mode 100644
index 00000000000..f3480fcc9ee
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs
@@ -0,0 +1,86 @@
+// check-pass
+
+#![crate_type = "lib"]
+#![allow(internal_features)]
+#![no_std]
+#![no_core]
+#![feature(
+    auto_traits,
+    const_trait_impl,
+    effects,
+    lang_items,
+    no_core,
+    staged_api,
+    unboxed_closures
+)]
+#![stable(feature = "minicore", since = "1.0.0")]
+
+fn test() {
+    fn is_const_fn<F>(_: F)
+    where
+        F: const FnOnce<()>,
+    {
+    }
+
+    const fn foo() {}
+
+    is_const_fn(foo);
+}
+
+/// ---------------------------------------------------------------------- ///
+/// Const fn trait definitions
+
+#[const_trait]
+#[lang = "fn"]
+#[rustc_paren_sugar]
+trait Fn<Args: Tuple>: ~const FnMut<Args> {
+    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[const_trait]
+#[lang = "fn_mut"]
+#[rustc_paren_sugar]
+trait FnMut<Args: Tuple>: ~const FnOnce<Args> {
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[const_trait]
+#[lang = "fn_once"]
+#[rustc_paren_sugar]
+trait FnOnce<Args: Tuple> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+/// ---------------------------------------------------------------------- ///
+/// All this other stuff needed for core. Unrelated to test.
+
+#[lang = "destruct"]
+#[const_trait]
+trait Destruct {}
+
+#[lang = "freeze"]
+unsafe auto trait Freeze {}
+
+#[lang = "drop"]
+#[const_trait]
+trait Drop {
+    fn drop(&mut self);
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "tuple_trait"]
+trait Tuple {}
+
+#[lang = "receiver"]
+trait Receiver {}
+
+impl<T: ?Sized> Receiver for &T {}
+
+impl<T: ?Sized> Receiver for &mut T {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs
index 14d306fc31f..9d579e67a4b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.rs
@@ -1,4 +1,6 @@
 // known-bug: #110395
+// Broken until we have `&T: const Deref` impl in stdlib
+
 #![allow(incomplete_features)]
 #![feature(
     associated_type_bounds,
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
index d0ca1b19ad1..d4be71f2f46 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `()` with `()`
-  --> $DIR/const-impl-trait.rs:35:17
+  --> $DIR/const-impl-trait.rs:37:17
    |
 LL |     assert!(cmp(&()));
    |             --- ^^^ no implementation for `() == ()`
@@ -9,23 +9,20 @@ LL |     assert!(cmp(&()));
    = help: the trait `const PartialEq` is not implemented for `()`
    = help: the trait `PartialEq` is implemented for `()`
 note: required by a bound in `cmp`
-  --> $DIR/const-impl-trait.rs:12:23
+  --> $DIR/const-impl-trait.rs:14:23
    |
 LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
    |                       ^^^^^^^^^^^^^^^^ required by this bound in `cmp`
 
-error[E0277]: can't compare `&impl ~const PartialEq` with `&impl ~const PartialEq`
-  --> $DIR/const-impl-trait.rs:13:7
+error[E0369]: binary operation `==` cannot be applied to type `&impl ~const PartialEq`
+  --> $DIR/const-impl-trait.rs:15:7
    |
 LL |     a == a
-   |       ^^ no implementation for `&impl ~const PartialEq == &impl ~const PartialEq`
-   |
-   = help: the trait `~const PartialEq<&impl ~const PartialEq>` is not implemented for `&impl ~const PartialEq`
-help: consider dereferencing both sides of the expression
-   |
-LL |     *a == *a
-   |     +     +
+   |     - ^^ - &impl ~const PartialEq
+   |     |
+   |     &impl ~const PartialEq
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0277, E0369.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
index 59fb48e794c..84d9bcd7ac9 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
@@ -40,7 +40,7 @@ const fn bar() {
 
 #[lang = "Try"]
 #[const_trait]
-trait Try: FromResidual {
+trait Try: FromResidual<Self::Residual> {
     type Output;
     type Residual;
 
@@ -53,7 +53,7 @@ trait Try: FromResidual {
 
 // FIXME
 // #[const_trait]
-trait FromResidual<R = <Self as Try>::Residual> {
+trait FromResidual<R = <Self as /* FIXME: ~const */ Try>::Residual> {
     #[lang = "from_residual"]
     fn from_residual(residual: R) -> Self;
 }
@@ -519,9 +519,14 @@ extern "rust-intrinsic" {
         called_in_const: F,
         called_at_rt: G,
     ) -> RET
-    /* where clauses enforced by built-in method confirmation:
     where
-        F: const FnOnce<Arg, Output = RET>,
-        G: FnOnce<Arg, Output = RET>,
-     */;
+        F: const FnOnce<ARG, Output = RET>,
+        G: FnOnce<ARG, Output = RET>;
+}
+
+fn test_const_eval_select() {
+    const fn const_fn() {}
+    fn rt_fn() {}
+
+    unsafe { const_eval_select((), const_fn, rt_fn); }
 }
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs
index b30d7743edf..e22eed3e0ef 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs
@@ -1,7 +1,12 @@
-// check-pass
+// known-bug: #110395
+// FIXME: effects
+
 #![feature(const_trait_impl, effects)]
 
-pub trait Owo<X = <Self as Uwu>::T> {}
+// This fails because `~const Uwu` doesn't imply (non-const) `Uwu`.
+
+// FIXME: #[const_trait]
+pub trait Owo<X = <Self as /* FIXME: ~const */ Uwu>::T> {}
 
 #[const_trait]
 pub trait Uwu: Owo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr
new file mode 100644
index 00000000000..eac3ee9e4e2
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr
@@ -0,0 +1,65 @@
+error[E0277]: the trait bound `Self: Uwu` is not satisfied
+  --> $DIR/project.rs:12:1
+   |
+LL | pub trait Uwu: Owo {
+   | ^^^^^^^^^^^^^^^^^^ the trait `Uwu` is not implemented for `Self`
+   |
+help: consider further restricting `Self`
+   |
+LL | pub trait Uwu: Owo + Uwu {
+   |                    +++++
+
+error[E0277]: the trait bound `Self: Uwu` is not satisfied
+  --> $DIR/project.rs:12:1
+   |
+LL | / pub trait Uwu: Owo {
+LL | |     type T;
+LL | | }
+   | |_^ the trait `Uwu` is not implemented for `Self`
+   |
+help: consider further restricting `Self`
+   |
+LL | pub trait Uwu: Owo + Uwu {
+   |                    +++++
+
+error[E0277]: the trait bound `Self: Uwu` is not satisfied
+  --> $DIR/project.rs:12:16
+   |
+LL | pub trait Uwu: Owo {
+   |                ^^^ the trait `Uwu` is not implemented for `Self`
+   |
+note: required by a bound in `Owo`
+  --> $DIR/project.rs:9:15
+   |
+LL | pub trait Owo<X = <Self as /* FIXME: ~const */ Uwu>::T> {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Owo`
+help: consider further restricting `Self`
+   |
+LL | pub trait Uwu: Owo + Uwu {
+   |                    +++++
+
+error[E0277]: the trait bound `Self: Uwu` is not satisfied
+  --> $DIR/project.rs:13:5
+   |
+LL |     type T;
+   |     ^^^^^^ the trait `Uwu` is not implemented for `Self`
+   |
+help: consider further restricting `Self`
+   |
+LL | pub trait Uwu: Owo + Uwu {
+   |                    +++++
+
+error[E0277]: the trait bound `Self: Uwu` is not satisfied
+  --> $DIR/project.rs:13:5
+   |
+LL |     type T;
+   |     ^^^^^^^ the trait `Uwu` is not implemented for `Self`
+   |
+help: consider further restricting `Self`
+   |
+LL | pub trait Uwu: Owo + Uwu {
+   |                    +++++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
index 2a9647da782..0141dcfb06f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
@@ -1,21 +1,35 @@
-error[E0308]: mismatched types
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/trait-where-clause-const.rs:21:5
    |
 LL |     T::b();
-   |     ^^^^^^ expected `host`, found `true`
+   |     ^ the trait `~const Bar` is not implemented for `T`
    |
-   = note: expected constant `host`
-              found constant `true`
+note: required by a bound in `Foo::b`
+  --> $DIR/trait-where-clause-const.rs:15:24
+   |
+LL |     fn b() where Self: ~const Bar;
+   |                        ^^^^^^^^^^ required by this bound in `Foo::b`
+help: consider further restricting this bound
+   |
+LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
+   |                                    ++++++++++++
 
-error[E0308]: mismatched types
-  --> $DIR/trait-where-clause-const.rs:23:5
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
+  --> $DIR/trait-where-clause-const.rs:23:12
    |
 LL |     T::c::<T>();
-   |     ^^^^^^^^^^^ expected `host`, found `true`
+   |            ^ the trait `~const Bar` is not implemented for `T`
+   |
+note: required by a bound in `Foo::c`
+  --> $DIR/trait-where-clause-const.rs:16:13
+   |
+LL |     fn c<T: ~const Bar>();
+   |             ^^^^^^^^^^ required by this bound in `Foo::c`
+help: consider further restricting this bound
    |
-   = note: expected constant `host`
-              found constant `true`
+LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
+   |                                    ++++++++++++
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs
index 62a7b312378..8f441410c17 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs
@@ -30,4 +30,4 @@ fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
 // FIXME(effects): Instead of suggesting `+ const Trait`, suggest
 //                 changing `~const Trait` to `const Trait`.
 const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
-//~^ ERROR the trait bound `T: const Trait` is not satisfied
+//~^ ERROR mismatched types
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr
index 2fb4fc1aa2b..258f95b5c4a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr
@@ -7,16 +7,14 @@ LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
    = note: expected constant `false`
               found constant `true`
 
-error[E0277]: the trait bound `T: const Trait` is not satisfied
+error[E0308]: mismatched types
   --> $DIR/unsatisfied-const-trait-bound.rs:32:50
    |
 LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
-   |                                                  ^ the trait `const Trait` is not implemented for `T`
-   |
-help: consider further restricting this bound
+   |                                                  ^^^^^^^^^ expected `false`, found `host`
    |
-LL | const fn accept1<T: ~const Trait + const Trait>(_: Container<{ T::make() }>) {}
-   |                                  +++++++++++++
+   = note: expected constant `false`
+              found constant `host`
 
 error[E0277]: the trait bound `Ty: const Trait` is not satisfied
   --> $DIR/unsatisfied-const-trait-bound.rs:20:15
diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.rs b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.rs
new file mode 100644
index 00000000000..800735cf3a7
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.rs
@@ -0,0 +1,11 @@
+// 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 -Z shell-argfiles @shell:{{src-base}}\shell-argfiles\shell-argfiles-badquotes.args
+
+fn main() {
+}
diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr
new file mode 100644
index 00000000000..14adb1f740a
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes-windows.stderr
@@ -0,0 +1,2 @@
+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.args b/tests/ui/shell-argfiles/shell-argfiles-badquotes.args
new file mode 100644
index 00000000000..c0d531adf3f
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes.args
@@ -0,0 +1 @@
+"--cfg" "unquoted_set
diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes.rs b/tests/ui/shell-argfiles/shell-argfiles-badquotes.rs
new file mode 100644
index 00000000000..f9160143a04
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes.rs
@@ -0,0 +1,12 @@
+// 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 -Z shell-argfiles @shell:{{src-base}}/shell-argfiles/shell-argfiles-badquotes.args
+
+fn main() {
+}
diff --git a/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr b/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
new file mode 100644
index 00000000000..14adb1f740a
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
@@ -0,0 +1,2 @@
+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-via-argfile-shell.args b/tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args
new file mode 100644
index 00000000000..4e66d5a0395
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args
@@ -0,0 +1 @@
+"--cfg" "shell_args_set"
\ No newline at end of file
diff --git a/tests/ui/shell-argfiles/shell-argfiles-via-argfile.args b/tests/ui/shell-argfiles/shell-argfiles-via-argfile.args
new file mode 100644
index 00000000000..d0af54e24e3
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-via-argfile.args
@@ -0,0 +1 @@
+-Zshell-argfiles
\ No newline at end of file
diff --git a/tests/ui/shell-argfiles/shell-argfiles-via-argfile.rs b/tests/ui/shell-argfiles/shell-argfiles-via-argfile.rs
new file mode 100644
index 00000000000..d71e3218f53
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles-via-argfile.rs
@@ -0,0 +1,10 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// build-pass
+// compile-flags: @{{src-base}}/shell-argfiles/shell-argfiles-via-argfile.args @shell:{{src-base}}/shell-argfiles/shell-argfiles-via-argfile-shell.args
+
+#[cfg(not(shell_args_set))]
+compile_error!("shell_args_set not set");
+
+fn main() {
+}
diff --git a/tests/ui/shell-argfiles/shell-argfiles.args b/tests/ui/shell-argfiles/shell-argfiles.args
new file mode 100644
index 00000000000..e5bb4b807ec
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles.args
@@ -0,0 +1,3 @@
+--cfg unquoted_set
+'--cfg' 'single_quoted_set'
+"--cfg" "double_quoted_set"
diff --git a/tests/ui/shell-argfiles/shell-argfiles.rs b/tests/ui/shell-argfiles/shell-argfiles.rs
new file mode 100644
index 00000000000..9bc252ea628
--- /dev/null
+++ b/tests/ui/shell-argfiles/shell-argfiles.rs
@@ -0,0 +1,19 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// build-pass
+// compile-flags: --cfg cmdline_set -Z shell-argfiles @shell:{{src-base}}/shell-argfiles/shell-argfiles.args
+
+#[cfg(not(cmdline_set))]
+compile_error!("cmdline_set not set");
+
+#[cfg(not(unquoted_set))]
+compile_error!("unquoted_set not set");
+
+#[cfg(not(single_quoted_set))]
+compile_error!("single_quoted_set not set");
+
+#[cfg(not(double_quoted_set))]
+compile_error!("double_quoted_set not set");
+
+fn main() {
+}