Skip to content

Commit e4e5640

Browse files
committed
Rollup merge of #23274 - rprichard:fix-21715, r=pnkfelix
* Consumers of handle_options assume the unstable options are defined in the getopts::Matches value if -Z unstable-options is set, but that's not the case if there weren't any actual unstable options. Fix this by always reparsing options when -Z unstable-options is set. * If both argument parsing attempts fail, print the error from the second attempt rather than the first. The error from the first is very poor whenever unstable options are present. e.g.: $ rustc hello.rs -Z unstable-options --show-span error: Unrecognized option: 'show-span'. $ rustc hello.rs -Z unstable-options --pretty --pretty error: Unrecognized option: 'pretty'. $ rustc hello.rs -Z unstable-options --pretty --bad-option error: Unrecognized option: 'pretty'. * On the second parse, add a separate pass to reject unstable options if -Z unstable-options wasn't specified. Fixes #21715. r? @pnkfelix
2 parents 99dc60d + 61004f8 commit e4e5640

File tree

1 file changed

+43
-25
lines changed

1 file changed

+43
-25
lines changed

src/librustc_driver/lib.rs

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -686,39 +686,57 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
686686
return None;
687687
}
688688

689-
let matches =
690-
match getopts::getopts(&args[..], &config::optgroups()) {
691-
Ok(m) => m,
692-
Err(f_stable_attempt) => {
693-
// redo option parsing, including unstable options this time,
694-
// in anticipation that the mishandled option was one of the
695-
// unstable ones.
696-
let all_groups : Vec<getopts::OptGroup>
697-
= config::rustc_optgroups().into_iter().map(|x|x.opt_group).collect();
698-
match getopts::getopts(&args, &all_groups) {
699-
Ok(m_unstable) => {
700-
let r = m_unstable.opt_strs("Z");
701-
let include_unstable_options = r.iter().any(|x| *x == "unstable-options");
702-
if include_unstable_options {
703-
m_unstable
689+
fn allows_unstable_options(matches: &getopts::Matches) -> bool {
690+
let r = matches.opt_strs("Z");
691+
r.iter().any(|x| *x == "unstable-options")
692+
}
693+
694+
fn parse_all_options(args: &Vec<String>) -> getopts::Matches {
695+
let all_groups : Vec<getopts::OptGroup>
696+
= config::rustc_optgroups().into_iter().map(|x|x.opt_group).collect();
697+
match getopts::getopts(&args[..], &all_groups) {
698+
Ok(m) => {
699+
if !allows_unstable_options(&m) {
700+
// If -Z unstable-options was not specified, verify that
701+
// no unstable options were present.
702+
for opt in config::rustc_optgroups().into_iter().filter(|x| !x.is_stable()) {
703+
let opt_name = if !opt.opt_group.long_name.is_empty() {
704+
&opt.opt_group.long_name
704705
} else {
705-
early_error(&f_stable_attempt.to_string());
706+
&opt.opt_group.short_name
707+
};
708+
if m.opt_present(opt_name) {
709+
early_error(&format!("use of unstable option '{}' requires \
710+
-Z unstable-options", opt_name));
706711
}
707712
}
708-
Err(_) => {
709-
// ignore the error from the unstable attempt; just
710-
// pass the error we got from the first try.
711-
early_error(&f_stable_attempt.to_string());
712-
}
713713
}
714+
m
714715
}
715-
};
716+
Err(f) => early_error(&f.to_string())
717+
}
718+
}
716719

717-
let r = matches.opt_strs("Z");
718-
let include_unstable_options = r.iter().any(|x| *x == "unstable-options");
720+
// As a speed optimization, first try to parse the command-line using just
721+
// the stable options.
722+
let matches = match getopts::getopts(&args[..], &config::optgroups()) {
723+
Ok(ref m) if allows_unstable_options(m) => {
724+
// If -Z unstable-options was specified, redo parsing with the
725+
// unstable options to ensure that unstable options are defined
726+
// in the returned getopts::Matches.
727+
parse_all_options(&args)
728+
}
729+
Ok(m) => m,
730+
Err(_) => {
731+
// redo option parsing, including unstable options this time,
732+
// in anticipation that the mishandled option was one of the
733+
// unstable ones.
734+
parse_all_options(&args)
735+
}
736+
};
719737

720738
if matches.opt_present("h") || matches.opt_present("help") {
721-
usage(matches.opt_present("verbose"), include_unstable_options);
739+
usage(matches.opt_present("verbose"), allows_unstable_options(&matches));
722740
return None;
723741
}
724742

0 commit comments

Comments
 (0)