Skip to content

Commit ae9d24d

Browse files
committed
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
2 parents 5876c8c + d61b92f commit ae9d24d

35 files changed

+414
-151
lines changed

Cargo.lock

+3-2
Original file line numberDiff line numberDiff line change
@@ -704,9 +704,9 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"
704704

705705
[[package]]
706706
name = "compiler_builtins"
707-
version = "0.1.103"
707+
version = "0.1.104"
708708
source = "registry+https://github.com/rust-lang/crates.io-index"
709-
checksum = "a3b73c3443a5fd2438d7ba4853c64e4c8efc2404a9e28a9234cc2d5eebc6c242"
709+
checksum = "99c3f9035afc33f4358773239573f7d121099856753e1bbd2a6a5207098fc741"
710710
dependencies = [
711711
"cc",
712712
"rustc-std-workspace-core",
@@ -3738,6 +3738,7 @@ dependencies = [
37383738
"rustc_trait_selection",
37393739
"rustc_ty_utils",
37403740
"serde_json",
3741+
"shlex",
37413742
"time",
37423743
"tracing",
37433744
"windows",

compiler/rustc_driver_impl/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ rustc_target = { path = "../rustc_target" }
5050
rustc_trait_selection = { path = "../rustc_trait_selection" }
5151
rustc_ty_utils = { path = "../rustc_ty_utils" }
5252
serde_json = "1.0.59"
53+
shlex = "1.0"
5354
time = { version = "0.3", default-features = false, features = ["alloc", "formatting"] }
5455
tracing = { version = "0.1.35" }
5556
# tidy-alphabetical-end

compiler/rustc_driver_impl/src/args.rs

+91-16
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,113 @@ use std::io;
55

66
use rustc_session::EarlyDiagCtxt;
77

8-
fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
9-
if let Some(path) = arg.strip_prefix('@') {
10-
let file = match fs::read_to_string(path) {
11-
Ok(file) => file,
12-
Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
13-
return Err(Error::Utf8Error(Some(path.to_string())));
8+
/// Expands argfiles in command line arguments.
9+
#[derive(Default)]
10+
struct Expander {
11+
shell_argfiles: bool,
12+
next_is_unstable_option: bool,
13+
expanded: Vec<String>,
14+
}
15+
16+
impl Expander {
17+
/// Handles the next argument. If the argument is an argfile, it is expanded
18+
/// inline.
19+
fn arg(&mut self, arg: &str) -> Result<(), Error> {
20+
if let Some(argfile) = arg.strip_prefix('@') {
21+
match argfile.split_once(':') {
22+
Some(("shell", path)) if self.shell_argfiles => {
23+
shlex::split(&Self::read_file(path)?)
24+
.ok_or_else(|| Error::ShellParseError(path.to_string()))?
25+
.into_iter()
26+
.for_each(|arg| self.push(arg));
27+
}
28+
_ => {
29+
let contents = Self::read_file(argfile)?;
30+
contents.lines().for_each(|arg| self.push(arg.to_string()));
31+
}
32+
}
33+
} else {
34+
self.push(arg.to_string());
35+
}
36+
37+
Ok(())
38+
}
39+
40+
/// Adds a command line argument verbatim with no argfile expansion.
41+
fn push(&mut self, arg: String) {
42+
// Unfortunately, we have to do some eager argparsing to handle unstable
43+
// options which change the behavior of argfile arguments.
44+
//
45+
// Normally, all of the argfile arguments (e.g. `@args.txt`) are
46+
// expanded into our arguments list *and then* the whole list of
47+
// arguments are passed on to be parsed. However, argfile parsing
48+
// options like `-Zshell_argfiles` need to change the behavior of that
49+
// argument expansion. So we have to do a little parsing on our own here
50+
// instead of leaning on the existing logic.
51+
//
52+
// All we care about are unstable options, so we parse those out and
53+
// look for any that affect how we expand argfiles. This argument
54+
// inspection is very conservative; we only change behavior when we see
55+
// exactly the options we're looking for and everything gets passed
56+
// through.
57+
58+
if self.next_is_unstable_option {
59+
self.inspect_unstable_option(&arg);
60+
self.next_is_unstable_option = false;
61+
} else if let Some(unstable_option) = arg.strip_prefix("-Z") {
62+
if unstable_option.is_empty() {
63+
self.next_is_unstable_option = true;
64+
} else {
65+
self.inspect_unstable_option(unstable_option);
66+
}
67+
}
68+
69+
self.expanded.push(arg);
70+
}
71+
72+
/// Consumes the `Expander`, returning the expanded arguments.
73+
fn finish(self) -> Vec<String> {
74+
self.expanded
75+
}
76+
77+
/// Parses any relevant unstable flags specified on the command line.
78+
fn inspect_unstable_option(&mut self, option: &str) {
79+
match option {
80+
"shell-argfiles" => self.shell_argfiles = true,
81+
_ => (),
82+
}
83+
}
84+
85+
/// Reads the contents of a file as UTF-8.
86+
fn read_file(path: &str) -> Result<String, Error> {
87+
fs::read_to_string(path).map_err(|e| {
88+
if e.kind() == io::ErrorKind::InvalidData {
89+
Error::Utf8Error(Some(path.to_string()))
90+
} else {
91+
Error::IOError(path.to_string(), e)
1492
}
15-
Err(err) => return Err(Error::IOError(path.to_string(), err)),
16-
};
17-
Ok(file.lines().map(ToString::to_string).collect())
18-
} else {
19-
Ok(vec![arg])
93+
})
2094
}
2195
}
2296

2397
/// **Note:** This function doesn't interpret argument 0 in any special way.
2498
/// If this function is intended to be used with command line arguments,
2599
/// `argv[0]` must be removed prior to calling it manually.
26100
pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<String> {
27-
let mut args = Vec::new();
101+
let mut expander = Expander::default();
28102
for arg in at_args {
29-
match arg_expand(arg.clone()) {
30-
Ok(arg) => args.extend(arg),
31-
Err(err) => early_dcx.early_fatal(format!("Failed to load argument file: {err}")),
103+
if let Err(err) = expander.arg(arg) {
104+
early_dcx.early_fatal(format!("Failed to load argument file: {err}"));
32105
}
33106
}
34-
args
107+
expander.finish()
35108
}
36109

37110
#[derive(Debug)]
38111
pub enum Error {
39112
Utf8Error(Option<String>),
40113
IOError(String, io::Error),
114+
ShellParseError(String),
41115
}
42116

43117
impl fmt::Display for Error {
@@ -46,6 +120,7 @@ impl fmt::Display for Error {
46120
Error::Utf8Error(None) => write!(fmt, "Utf8 error"),
47121
Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {path}"),
48122
Error::IOError(path, err) => write!(fmt, "IO Error: {path}: {err}"),
123+
Error::ShellParseError(path) => write!(fmt, "Invalid shell-style arguments in {path}"),
49124
}
50125
}
51126
}

compiler/rustc_hir_analysis/src/astconv/mod.rs

+2-33
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10321032
self.trait_defines_associated_item_named(r.def_id(), assoc_kind, assoc_name)
10331033
});
10341034

1035-
let Some(mut bound) = matching_candidates.next() else {
1035+
let Some(bound) = matching_candidates.next() else {
10361036
let reported = self.complain_about_assoc_item_not_found(
10371037
all_candidates,
10381038
&ty_param_name.to_string(),
@@ -1046,38 +1046,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10461046
};
10471047
debug!(?bound);
10481048

1049-
// look for a candidate that is not the same as our first bound, disregarding
1050-
// whether the bound is const.
1051-
let mut next_cand = matching_candidates.next();
1052-
while let Some(mut bound2) = next_cand {
1053-
debug!(?bound2);
1054-
if bound2.bound_vars() != bound.bound_vars() {
1055-
break;
1056-
}
1057-
1058-
let generics = tcx.generics_of(bound.def_id());
1059-
let Some(host_index) = generics.host_effect_index else { break };
1060-
1061-
// always return the bound that contains the host param.
1062-
if let ty::ConstKind::Param(_) = bound2.skip_binder().args.const_at(host_index).kind() {
1063-
(bound, bound2) = (bound2, bound);
1064-
}
1065-
1066-
let unconsted_args = bound
1067-
.skip_binder()
1068-
.args
1069-
.iter()
1070-
.enumerate()
1071-
.map(|(n, arg)| if host_index == n { tcx.consts.true_.into() } else { arg });
1072-
1073-
if unconsted_args.eq(bound2.skip_binder().args.iter()) {
1074-
next_cand = matching_candidates.next();
1075-
} else {
1076-
break;
1077-
}
1078-
}
1079-
1080-
if let Some(bound2) = next_cand {
1049+
if let Some(bound2) = matching_candidates.next() {
10811050
debug!(?bound2);
10821051

10831052
let assoc_kind_str = assoc_kind_str(assoc_kind);

compiler/rustc_hir_analysis/src/bounds.rs

-18
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,6 @@ impl<'tcx> Bounds<'tcx> {
4545
polarity: ty::ImplPolarity,
4646
) {
4747
self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
48-
49-
// push a non-const (`host = true`) version of the bound if it is `~const`.
50-
if tcx.features().effects
51-
&& let Some(host_effect_idx) = tcx.generics_of(trait_ref.def_id()).host_effect_index
52-
&& trait_ref.skip_binder().args.const_at(host_effect_idx) != tcx.consts.true_
53-
{
54-
let generics = tcx.generics_of(trait_ref.def_id());
55-
let Some(host_index) = generics.host_effect_index else { return };
56-
let trait_ref = trait_ref.map_bound(|mut trait_ref| {
57-
trait_ref.args =
58-
tcx.mk_args_from_iter(trait_ref.args.iter().enumerate().map(|(n, arg)| {
59-
if host_index == n { tcx.consts.true_.into() } else { arg }
60-
}));
61-
trait_ref
62-
});
63-
64-
self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
65-
}
6648
}
6749

6850
fn push_trait_bound_inner(

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+6-32
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_hir::intravisit::{self, Visitor};
1111
use rustc_middle::ty::{self, Ty, TyCtxt};
1212
use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate};
1313
use rustc_span::symbol::Ident;
14-
use rustc_span::{sym, Span, DUMMY_SP};
14+
use rustc_span::{Span, DUMMY_SP};
1515

1616
/// Returns a list of all type predicates (explicit and implicit) for the definition with
1717
/// 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
3838
// an obligation and instead be skipped. Otherwise we'd use
3939
// `tcx.def_span(def_id);`
4040
let span = rustc_span::DUMMY_SP;
41-
let non_const_bound = if tcx.features().effects && tcx.has_attr(def_id, sym::const_trait) {
42-
// when `Self` is a const trait, also add `Self: Trait<.., true>` as implied bound,
43-
// because only implementing `Self: Trait<.., false>` is currently not possible.
44-
Some((
45-
ty::TraitRef::new(
46-
tcx,
47-
def_id,
48-
ty::GenericArgs::for_item(tcx, def_id, |param, _| {
49-
if param.is_host_effect() {
50-
tcx.consts.true_.into()
51-
} else {
52-
tcx.mk_param_from_def(param)
53-
}
54-
}),
55-
)
56-
.to_predicate(tcx),
41+
42+
result.predicates =
43+
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
44+
ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
5745
span,
58-
))
59-
} else {
60-
None
61-
};
62-
result.predicates = tcx.arena.alloc_from_iter(
63-
result
64-
.predicates
65-
.iter()
66-
.copied()
67-
.chain(std::iter::once((
68-
ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
69-
span,
70-
)))
71-
.chain(non_const_bound),
72-
);
46+
))));
7347
}
7448
debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
7549
result

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ fn test_unstable_options_tracking_hash() {
698698
untracked!(query_dep_graph, true);
699699
untracked!(self_profile, SwitchWithOptPath::Enabled(None));
700700
untracked!(self_profile_events, Some(vec![String::new()]));
701+
untracked!(shell_argfiles, true);
701702
untracked!(span_debug, true);
702703
untracked!(span_free_formats, true);
703704
untracked!(temps_dir, Some(String::from("abc")));

compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1841,6 +1841,8 @@ written to standard error output)"),
18411841
query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"),
18421842
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
18431843
"make the current crate share its generic instantiations"),
1844+
shell_argfiles: bool = (false, parse_bool, [UNTRACKED],
1845+
"allow argument files to be specified with POSIX \"shell-style\" argument quoting"),
18441846
show_span: Option<String> = (None, parse_opt_string, [TRACKED],
18451847
"show spans for compiler debugging (expr|pat|ty)"),
18461848
simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],

library/core/src/macros/panic.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ For more detailed information about error handling check out the [book] or the
5656
[`panic_any`]: ../std/panic/fn.panic_any.html
5757
[`Box`]: ../std/boxed/struct.Box.html
5858
[`Any`]: crate::any::Any
59-
[`format!` syntax]: ../std/fmt/index.html
59+
[formatting syntax]: ../std/fmt/index.html
6060
[book]: ../book/ch09-00-error-handling.html
6161
[`std::result`]: ../std/result/index.html
6262

library/std/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
1818
panic_abort = { path = "../panic_abort" }
1919
core = { path = "../core", public = true }
2020
libc = { version = "0.2.150", default-features = false, features = ['rustc-dep-of-std'], public = true }
21-
compiler_builtins = { version = "0.1.103" }
21+
compiler_builtins = { version = "0.1.104" }
2222
profiler_builtins = { path = "../profiler_builtins", optional = true }
2323
unwind = { path = "../unwind" }
2424
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
5454
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
5555

5656
[target.'cfg(target_os = "uefi")'.dependencies]
57-
r-efi = { version = "4.2.0", features = ['rustc-dep-of-std']}
58-
r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std']}
57+
r-efi = { version = "4.2.0", features = ['rustc-dep-of-std'] }
58+
r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] }
5959

6060
[features]
6161
backtrace = [

library/std/src/sys/sgx/abi/usercalls/alloc.rs

+6
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ pub struct UserRef<T: ?Sized>(UnsafeCell<T>);
185185
#[unstable(feature = "sgx_platform", issue = "56975")]
186186
pub struct User<T: UserSafe + ?Sized>(NonNull<UserRef<T>>);
187187

188+
#[unstable(feature = "sgx_platform", issue = "56975")]
189+
unsafe impl<T: UserSafeSized> Send for User<T> {}
190+
191+
#[unstable(feature = "sgx_platform", issue = "56975")]
192+
unsafe impl<T: UserSafeSized> Send for User<[T]> {}
193+
188194
trait NewUserRef<T: ?Sized> {
189195
unsafe fn new_userref(v: T) -> Self;
190196
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# `shell-argfiles`
2+
3+
--------------------
4+
5+
The `-Zshell-argfiles` compiler flag allows argfiles to be parsed using POSIX
6+
"shell-style" quoting. When enabled, the compiler will use `shlex` to parse the
7+
arguments from argfiles specified with `@shell:<path>`.
8+
9+
Because this feature controls the parsing of input arguments, the
10+
`-Zshell-argfiles` flag must be present before the argument specifying the
11+
shell-style arguemnt file.

src/tools/tidy/src/deps.rs

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
325325
"sha1",
326326
"sha2",
327327
"sharded-slab",
328+
"shlex",
328329
"smallvec",
329330
"snap",
330331
"stable_deref_trait",

src/tools/tidy/src/ui_tests.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
1111
const ENTRY_LIMIT: usize = 900;
1212
// FIXME: The following limits should be reduced eventually.
1313
const ISSUES_ENTRY_LIMIT: usize = 1849;
14-
const ROOT_ENTRY_LIMIT: usize = 867;
14+
const ROOT_ENTRY_LIMIT: usize = 868;
1515

1616
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
1717
"rs", // test source files
@@ -35,6 +35,10 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
3535
"tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
3636
"tests/ui/proc-macro/auxiliary/included-file.txt", // more include
3737
"tests/ui/invalid/foo.natvis.xml", // sample debugger visualizer
38+
"tests/ui/shell-argfiles/shell-argfiles.args", // passing args via a file
39+
"tests/ui/shell-argfiles/shell-argfiles-badquotes.args", // passing args via a file
40+
"tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args", // passing args via a file
41+
"tests/ui/shell-argfiles/shell-argfiles-via-argfile.args", // passing args via a file
3842
];
3943

4044
fn check_entries(tests_path: &Path, bad: &mut bool) {

0 commit comments

Comments
 (0)