From faf3861bf120786479269a3634015155d5c4cec5 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 15:53:05 -0600 Subject: [PATCH] fix(parser): Loosen asserts for now This is a surgical workaround for #3263. It makes `cargo` pass tests! --- src/parse/arg_matcher.rs | 6 ++++++ src/parse/matches/arg_matches.rs | 13 +++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/parse/arg_matcher.rs b/src/parse/arg_matcher.rs index 58a94059c46..9e5a59c0351 100644 --- a/src/parse/arg_matcher.rs +++ b/src/parse/arg_matcher.rs @@ -25,6 +25,12 @@ impl ArgMatcher { }, #[cfg(debug_assertions)] valid_subcommands: _app.subcommands.iter().map(|sc| sc.id.clone()).collect(), + // HACK: Allow an external subcommand's ArgMatches be a stand-in for any ArgMatches + // since users can't detect it and avoid the asserts. + // + // See clap-rs/clap#3263 + #[cfg(debug_assertions)] + disable_asserts: _app.is_set(crate::AppSettings::AllowExternalSubcommands), ..Default::default() }) } diff --git a/src/parse/matches/arg_matches.rs b/src/parse/matches/arg_matches.rs index 91a5841cae2..cc6c8781263 100644 --- a/src/parse/matches/arg_matches.rs +++ b/src/parse/matches/arg_matches.rs @@ -73,6 +73,8 @@ pub struct ArgMatches { pub(crate) valid_args: Vec, #[cfg(debug_assertions)] pub(crate) valid_subcommands: Vec, + #[cfg(debug_assertions)] + pub(crate) disable_asserts: bool, pub(crate) args: IndexMap, pub(crate) subcommand: Option>, } @@ -1005,7 +1007,7 @@ impl ArgMatches { #[cfg(debug_assertions)] { let id = Id::from(_id); - id == Id::empty_hash() || self.valid_args.contains(&id) + self.disable_asserts || id == Id::empty_hash() || self.valid_args.contains(&id) } #[cfg(not(debug_assertions))] { @@ -1024,7 +1026,7 @@ impl ArgMatches { #[cfg(debug_assertions)] { let id = Id::from(_id); - id == Id::empty_hash() || self.valid_subcommands.contains(&id) + self.disable_asserts || id == Id::empty_hash() || self.valid_subcommands.contains(&id) } #[cfg(not(debug_assertions))] { @@ -1040,7 +1042,7 @@ impl ArgMatches { fn get_arg(&self, arg: &Id) -> Option<&MatchedArg> { #[cfg(debug_assertions)] { - if *arg == Id::empty_hash() || self.valid_args.contains(arg) { + if self.disable_asserts || *arg == Id::empty_hash() || self.valid_args.contains(arg) { } else if self.valid_subcommands.contains(arg) { panic!( "Subcommand `{:?}` used where an argument or group name was expected.", @@ -1064,7 +1066,10 @@ impl ArgMatches { fn get_subcommand(&self, id: &Id) -> Option<&SubCommand> { #[cfg(debug_assertions)] { - if *id == Id::empty_hash() || self.valid_subcommands.contains(id) { + if self.disable_asserts + || *id == Id::empty_hash() + || self.valid_subcommands.contains(id) + { } else if self.valid_args.contains(id) { panic!( "Argument or group `{:?}` used where a subcommand name was expected.",