Skip to content

Commit adbdf8d

Browse files
committed
Allow invoking all help options at once
1 parent 74fd751 commit adbdf8d

2 files changed

Lines changed: 78 additions & 16 deletions

File tree

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
228228

229229
let args = args::arg_expand_all(&default_early_dcx, at_args);
230230

231-
let Some(matches) = handle_options(&default_early_dcx, &args) else {
232-
return;
231+
let (matches, help_only) = match handle_options(&default_early_dcx, &args) {
232+
HandledOptions::None => return,
233+
HandledOptions::Normal(matches) => (matches, false),
234+
HandledOptions::HelpOnly(matches) => (matches, true),
233235
};
234236

235237
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
@@ -291,6 +293,11 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
291293
return early_exit();
292294
}
293295

296+
// We have now handled all help options, exit
297+
if help_only {
298+
return early_exit();
299+
}
300+
294301
if print_crate_info(codegen_backend, sess, has_input) == Compilation::Stop {
295302
return early_exit();
296303
}
@@ -1092,7 +1099,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
10921099
// Don't handle -W help here, because we might first load additional lints.
10931100
let debug_flags = matches.opt_strs("Z");
10941101
if debug_flags.iter().any(|x| *x == "help") {
1095-
describe_debug_flags();
1102+
describe_unstable_flags();
10961103
return true;
10971104
}
10981105

@@ -1131,8 +1138,8 @@ fn get_backend_from_raw_matches(
11311138
get_codegen_backend(early_dcx, &sysroot, backend_name, &target)
11321139
}
11331140

1134-
fn describe_debug_flags() {
1135-
safe_println!("\nAvailable options:\n");
1141+
fn describe_unstable_flags() {
1142+
safe_println!("\nAvailable unstable options:\n");
11361143
print_flag_list("-Z", config::Z_OPTIONS);
11371144
}
11381145

@@ -1156,6 +1163,16 @@ fn print_flag_list<T>(cmdline_opt: &str, flag_list: &[OptionDesc<T>]) {
11561163
}
11571164
}
11581165

1166+
pub enum HandledOptions {
1167+
/// Parsing failed, or we parsed a flag causing an early exit
1168+
None,
1169+
/// Successful parsing
1170+
Normal(getopts::Matches),
1171+
/// Parsing succeeded, but we received one or more 'help' flags
1172+
/// The compiler should proceed only until a possible `-W help` flag has been processed
1173+
HelpOnly(getopts::Matches),
1174+
}
1175+
11591176
/// Process command line options. Emits messages as appropriate. If compilation
11601177
/// should continue, returns a getopts::Matches object parsed from args,
11611178
/// otherwise returns `None`.
@@ -1183,7 +1200,7 @@ fn print_flag_list<T>(cmdline_opt: &str, flag_list: &[OptionDesc<T>]) {
11831200
/// This does not need to be `pub` for rustc itself, but @chaosite needs it to
11841201
/// be public when using rustc as a library, see
11851202
/// <https://github.com/rust-lang/rust/commit/2b4c33817a5aaecabf4c6598d41e190080ec119e>
1186-
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<getopts::Matches> {
1203+
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> HandledOptions {
11871204
// Parse with *all* options defined in the compiler, we don't worry about
11881205
// option stability here we just want to parse as much as possible.
11891206
let mut options = getopts::Options::new();
@@ -1229,26 +1246,69 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
12291246
// (unstable option being used on stable)
12301247
nightly_options::check_nightly_options(early_dcx, &matches, &config::rustc_optgroups());
12311248

1232-
if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
1233-
// Only show unstable options in --help if we accept unstable options.
1234-
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
1235-
let nightly_build = nightly_options::match_is_nightly_build(&matches);
1236-
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
1237-
return None;
1249+
// Handle the special case of -Wall.
1250+
let wall = matches.opt_strs("W");
1251+
if wall.iter().any(|x| *x == "all") {
1252+
print_wall_help();
1253+
return HandledOptions::None;
12381254
}
12391255

1240-
if describe_flag_categories(early_dcx, &matches) {
1241-
return None;
1256+
if handle_help(&matches, args) {
1257+
return HandledOptions::HelpOnly(matches);
1258+
}
1259+
1260+
if matches.opt_strs("C").iter().any(|x| x == "passes=list") {
1261+
get_backend_from_raw_matches(early_dcx, &matches).print_passes();
1262+
return HandledOptions::None;
12421263
}
12431264

12441265
if matches.opt_present("version") {
12451266
version!(early_dcx, "rustc", &matches);
1246-
return None;
1267+
return HandledOptions::None;
12471268
}
12481269

12491270
warn_on_confusing_output_filename_flag(early_dcx, &matches, args);
12501271

1251-
Some(matches)
1272+
HandledOptions::Normal(matches)
1273+
}
1274+
1275+
/// Handle help options in the order they are provided, ignoring other flags. Returns if any options were handled
1276+
/// Handled options:
1277+
/// - `-h`/`--help`/empty arguments
1278+
/// - `-Z help`
1279+
/// - `-C help`
1280+
/// NOTE: `-W help` is NOT handled here, as additional lints may be loaded.
1281+
pub fn handle_help(matches: &getopts::Matches, args: &[String]) -> bool {
1282+
let opt_pos = |opt| matches.opt_positions(opt).first().copied();
1283+
let opt_help_pos = |opt| {
1284+
matches
1285+
.opt_strs_pos(opt)
1286+
.iter()
1287+
.filter_map(|(pos, oval)| if oval == "help" { Some(*pos) } else { None })
1288+
.next()
1289+
};
1290+
let help_pos = if args.is_empty() { Some(0) } else { opt_pos("h").or_else(|| opt_pos("help")) };
1291+
let zhelp_pos = opt_help_pos("Z");
1292+
let chelp_pos = opt_help_pos("C");
1293+
let print_help = || {
1294+
// Only show unstable options in --help if we accept unstable options.
1295+
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
1296+
let nightly_build = nightly_options::match_is_nightly_build(&matches);
1297+
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
1298+
};
1299+
1300+
let mut helps = [
1301+
(help_pos, &print_help as &dyn Fn()),
1302+
(zhelp_pos, &describe_unstable_flags),
1303+
(chelp_pos, &describe_codegen_flags),
1304+
];
1305+
helps.sort_by_key(|(pos, _)| pos.clone());
1306+
let mut printed_any = false;
1307+
for printer in helps.iter().filter_map(|(pos, func)| pos.is_some().then_some(func)) {
1308+
printer();
1309+
printed_any = true;
1310+
}
1311+
printed_any
12521312
}
12531313

12541314
/// Warn if `-o` is used without a space between the flag name and the value

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,7 @@ options! {
21252125
#[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
21262126
force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
21272127
"force use of unwind tables"),
2128+
help: bool = (false, parse_no_value, [UNTRACKED], "Print codegen options"),
21282129
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
21292130
"enable incremental compilation"),
21302131
#[rustc_lint_opt_deny_field_access("documented to do nothing")]
@@ -2395,6 +2396,7 @@ options! {
23952396
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
23962397
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
23972398
"explicitly enable the `cfg(target_thread_local)` directive"),
2399+
help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"),
23982400
higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED],
23992401
"allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"),
24002402
hint_mostly_unused: bool = (false, parse_bool, [TRACKED],

0 commit comments

Comments
 (0)