diff --git a/src/lib.rs b/src/lib.rs index b9b4de27..87dd42a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,8 @@ // HACK https://github.com/rust-lang/rust-clippy/issues/7290 #![allow(clippy::single_component_path_imports)] #![allow(clippy::branches_sharing_code)] +// Doesn't allow for debug statements, etc to be unique +#![allow(clippy::if_same_then_else)] #[cfg(not(feature = "std"))] compile_error!("`std` feature is currently required to build `clap`"); diff --git a/src/parse/parser.rs b/src/parse/parser.rs index d490f851..10e9b624 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1181,17 +1181,27 @@ impl<'help, 'app> Parser<'help, 'app> { debug!("Parser::parse_short_arg: short_arg={:?}", short_arg); let arg = short_arg.to_str_lossy(); - if (self.is_set(AS::AllowNegativeNumbers) && arg.parse::().is_ok()) - || (self.is_set(AS::AllowHyphenValues) - && arg.chars().any(|c| !self.app.contains_short(c))) - || matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) - if self.app[opt].is_set(ArgSettings::AllowHyphenValues)) - || self - .app - .args - .get(&pos_counter) - .map_or(false, |arg| arg.is_set(ArgSettings::AllowHyphenValues)) + #[allow(clippy::blocks_in_if_conditions)] + if self.is_set(AS::AllowNegativeNumbers) && arg.parse::().is_ok() { + debug!("Parser::parse_short_arg: negative number"); + return ParseResult::MaybeHyphenValue; + } else if self.is_set(AS::AllowHyphenValues) + && arg.chars().any(|c| !self.app.contains_short(c)) { + debug!("Parser::parse_short_args: contains non-short flag"); + return ParseResult::MaybeHyphenValue; + } else if matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) + if self.app[opt].is_set(ArgSettings::AllowHyphenValues)) + { + debug!("Parser::parse_short_args: prior arg accepts hyphenated values",); + return ParseResult::MaybeHyphenValue; + } else if self.app.args.get(&pos_counter).map_or(false, |arg| { + arg.is_set(ArgSettings::AllowHyphenValues) && !arg.is_set(ArgSettings::Last) + }) { + debug!( + "Parser::parse_short_args: positional at {} allows hyphens", + pos_counter + ); return ParseResult::MaybeHyphenValue; } diff --git a/tests/builder/positionals.rs b/tests/builder/positionals.rs index 6452aac2..e7f1a6d4 100644 --- a/tests/builder/positionals.rs +++ b/tests/builder/positionals.rs @@ -287,3 +287,24 @@ fn positional_arg_with_short() { .arg(Arg::new("arg").index(1).short('a')) .try_get_matches(); } + +#[test] +fn ignore_hyphen_values_on_last() { + let app = clap::App::new("foo") + .arg( + clap::Arg::new("cmd") + .multiple_values(true) + .last(true) + .allow_hyphen_values(true), + ) + .arg( + clap::Arg::new("name") + .long("name") + .short('n') + .takes_value(true) + .required(false), + ); + + let matches = app.try_get_matches_from(["test", "-n", "foo"]).unwrap(); + assert_eq!(matches.value_of("name"), Some("foo")); +}