Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #119630

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5c0e62c
Hide foreign `#[doc(hidden)]` paths in import suggestions
Jules-Bertholet Dec 20, 2023
5f56465
Make feature `negative_bounds` internal
fmease Dec 27, 2023
a251974
Deny parenthetical notation for negative bounds
fmease Dec 27, 2023
32cea61
Don't elaborate `!Sized` to `!Sized + Sized`
fmease Dec 27, 2023
977546d
rustc_middle: Pretty-print negative bounds correctly
fmease Dec 27, 2023
90d6fe2
Imply outlives-bounds on lazy type aliases
fmease Dec 27, 2023
1d48f69
Check yield terminator's resume type in borrowck
compiler-errors Jan 4, 2024
4bc3552
cstore: Remove unnecessary locking from `CrateMetadata`
petrochenkov Jan 4, 2024
407cb24
Remove `hir::Guard`
matthewjasper Sep 21, 2023
a549711
Remove `thir::Guard`
matthewjasper Sep 21, 2023
1a267e3
Restore if let guard temporary scoping difference
matthewjasper Jan 3, 2024
44bba54
Update clippy for hir::Guard removal
matthewjasper Jan 4, 2024
6a2bd5a
Use `resolutions(()).effective_visiblities` to avoid cycle errors
compiler-errors Jan 4, 2024
fdb70da
Add support for shell argfiles
djkoloski Dec 6, 2023
a721ccb
Rollup merge of #118680 - djkoloski:shell_argfiles, r=compiler-errors
matthiaskrgr Jan 5, 2024
7a00ce6
Rollup merge of #119151 - Jules-Bertholet:no-foreign-doc-hidden-sugge…
matthiaskrgr Jan 5, 2024
7e58b2f
Rollup merge of #119350 - fmease:lazy-ty-aliases-implied-bounds, r=co…
matthiaskrgr Jan 5, 2024
e0c86de
Rollup merge of #119354 - fmease:negative_bounds-fixes, r=compiler-er…
matthiaskrgr Jan 5, 2024
dd6b824
Rollup merge of #119506 - compiler-errors:visibilities-for-object-saf…
matthiaskrgr Jan 5, 2024
29a1770
Rollup merge of #119554 - matthewjasper:remove-guard-distinction, r=c…
matthiaskrgr Jan 5, 2024
ebbe615
Rollup merge of #119563 - compiler-errors:coroutine-resume, r=oli-obk
matthiaskrgr Jan 5, 2024
b4a7f1e
Rollup merge of #119589 - petrochenkov:cdatalock, r=Mark-Simulacrum
matthiaskrgr Jan 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add support for shell argfiles
  • Loading branch information
djkoloski committed Jan 5, 2024
commit fdb70da92e0459e86112ffd124220531cbd384e0
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3738,6 +3738,7 @@ dependencies = [
"rustc_trait_selection",
"rustc_ty_utils",
"serde_json",
"shlex",
"time",
"tracing",
"windows",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_driver_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
107 changes: 91 additions & 16 deletions compiler/rustc_driver_impl/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,113 @@ 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])
})
}
}

/// **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.
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 {
Expand All @@ -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}"),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,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")));
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,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],
Expand Down
11 changes: 11 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/shell-argfiles.md
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions src/tools/tidy/src/deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"sha1",
"sha2",
"sharded-slab",
"shlex",
"smallvec",
"snap",
"stable_deref_trait",
Expand Down
6 changes: 5 additions & 1 deletion src/tools/tidy/src/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -36,6 +36,10 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
"tests/ui/unused-crate-deps/test.mk", // why would you use make
"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) {
Expand Down
1 change: 1 addition & 0 deletions tests/ui/shell-argfiles/shell-argfiles-badquotes.args
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"--cfg" "unquoted_set
6 changes: 6 additions & 0 deletions tests/ui/shell-argfiles/shell-argfiles-badquotes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Check to see if we can get parameters from an @argsfile file
//
// compile-flags: --cfg cmdline_set -Z shell-argfiles @shell:{{src-base}}/shell-argfiles/shell-argfiles-badquotes.args

fn main() {
}
2 changes: 2 additions & 0 deletions tests/ui/shell-argfiles/shell-argfiles-badquotes.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: Failed to load argument file: Invalid shell-style arguments in $DIR/shell-argfiles-badquotes.args

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"--cfg" "shell_args_set"
1 change: 1 addition & 0 deletions tests/ui/shell-argfiles/shell-argfiles-via-argfile.args
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Zshell-argfiles
10 changes: 10 additions & 0 deletions tests/ui/shell-argfiles/shell-argfiles-via-argfile.rs
Original file line number Diff line number Diff line change
@@ -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() {
}
3 changes: 3 additions & 0 deletions tests/ui/shell-argfiles/shell-argfiles.args
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--cfg unquoted_set
'--cfg' 'single_quoted_set'
"--cfg" "double_quoted_set"
19 changes: 19 additions & 0 deletions tests/ui/shell-argfiles/shell-argfiles.rs
Original file line number Diff line number Diff line change
@@ -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() {
}