Fix #128930: Print documentation of CLI options missing their arg

This commit is contained in:
George Bateman 2024-08-11 09:07:52 +01:00
parent b389b0ab72
commit 6360287fd9
No known key found for this signature in database
GPG key ID: C417AA9C4039EFCF
4 changed files with 22 additions and 3 deletions

View file

@ -1221,17 +1221,30 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
// Parse with *all* options defined in the compiler, we don't worry about
// option stability here we just want to parse as much as possible.
let mut options = getopts::Options::new();
for option in config::rustc_optgroups() {
let optgroups = config::rustc_optgroups();
for option in &optgroups {
(option.apply)(&mut options);
}
let matches = options.parse(args).unwrap_or_else(|e| {
let msg = match e {
let msg: Option<String> = match e {
getopts::Fail::UnrecognizedOption(ref opt) => CG_OPTIONS
.iter()
.map(|&(name, ..)| ('C', name))
.chain(Z_OPTIONS.iter().map(|&(name, ..)| ('Z', name)))
.find(|&(_, name)| *opt == name.replace('_', "-"))
.map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
getopts::Fail::ArgumentMissing(ref opt) => {
optgroups.iter().find(|option| option.name == opt).map(|option| {
// Print the help just for the option in question.
let mut options = getopts::Options::new();
(option.apply)(&mut options);
// getopt requires us to pass a function for joining an iterator of
// strings, even though in this case we expect exactly one string.
options.usage_with_format(|it| {
it.fold(format!("{e}\nUsage:"), |a, b| a + "\n" + &b)
})
})
}
_ => None,
};
early_dcx.early_fatal(msg.unwrap_or_else(|| e.to_string()));