Repository: clap-rs/clap
Pull request #4262 (2022-09-26 18:30:10)

fix(parser): Conflict-with-self is back on by default
See #4261 for more details

<!--
Thanks for helping out!

Please link the appropriate issue from your PR.

If you don't have an issue, we'd recommend starting with one first so the PR can focus on the
implementation (unless its an obvious bug or documentation fix that will have
little conversation).
-->



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f4a810e2..1388fec6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -183,6 +183,9 @@ Subtle changes (i.e. compiler won't catch):
   - `ArgAction::Count`, requiring `ArgMatches::get_count` instead of `ArgMatches::occurrences_of`
   - `ArgAction::Set`, requiring `ArgMatches::get_one` instead of `ArgMatches::value_of`
   - `ArgAction::Append`, requiring `ArgMatches::get_many` instead of `ArgMatches::values_of`
+- `ArgAction::Set`, `ArgAction::SetTrue`, and `Arg::Action::SetFalse` now
+  conflict by default to be like `ArgAction::StoreValue` and
+  `ArgAction::IncOccurrences`, requiring `cmd.args_override_self(true)` to override instead (#4261)
 - By default, an `Arg`s default action is `ArgAction::Set`, rather than `ArgAction::IncOccurrence` to reduce confusing magic through consistency (#2687, #4032, see also #3977)
 - `mut_arg` can no longer be used to customize help and version arguments, instead disable them (`Command::disable_help_flag`, `Command::disable_version_flag`) and provide your own (#4056)
 - Removed lifetimes from `Command`, `Arg`, `ArgGroup`, and `PossibleValue`, assuming `'static`.  `string` feature flag will enable support for `String`s (#1041, #2150, #4223)
diff --git a/examples/tutorial_builder/03_01_flag_bool.md b/examples/tutorial_builder/03_01_flag_bool.md
index c151af44..0842935f 100644
--- a/examples/tutorial_builder/03_01_flag_bool.md
+++ b/examples/tutorial_builder/03_01_flag_bool.md
@@ -16,6 +16,11 @@ $ 03_01_flag_bool --verbose
 verbose: true
 
 $ 03_01_flag_bool --verbose --verbose
-verbose: true
+? failed
+error: The argument '--verbose' cannot be used with '--verbose'
+
+Usage: 03_01_flag_bool[EXE] [OPTIONS]
+
+For more information try '--help'
 
 ```
diff --git a/examples/tutorial_derive/03_01_flag_bool.md b/examples/tutorial_derive/03_01_flag_bool.md
index b5bfe58d..77975698 100644
--- a/examples/tutorial_derive/03_01_flag_bool.md
+++ b/examples/tutorial_derive/03_01_flag_bool.md
@@ -16,6 +16,11 @@ $ 03_01_flag_bool_derive --verbose
 verbose: true
 
 $ 03_01_flag_bool_derive --verbose --verbose
-verbose: true
+? failed
+error: The argument '--verbose' cannot be used with '--verbose'
+
+Usage: 03_01_flag_bool_derive[EXE] [OPTIONS]
+
+For more information try '--help'
 
 ```
diff --git a/src/builder/action.rs b/src/builder/action.rs
index 7cd3e017..dc7b79a7 100644
--- a/src/builder/action.rs
+++ b/src/builder/action.rs
@@ -27,6 +27,10 @@
 pub enum ArgAction {
     /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches]
     ///
+    /// **NOTE:** If the argument has previously been seen, it will result in a
+    /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless
+    /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set.
+    ///
     /// # Examples
     ///
     /// ```rust
@@ -76,6 +80,10 @@ pub enum ArgAction {
     /// No value is allowed. To optionally accept a value, see
     /// [`Arg::default_missing_value`][super::Arg::default_missing_value]
     ///
+    /// **NOTE:** If the argument has previously been seen, it will result in a
+    /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless
+    /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set.
+    ///
     /// # Examples
     ///
     /// ```rust
@@ -88,7 +96,7 @@ pub enum ArgAction {
     ///             .action(clap::ArgAction::SetTrue)
     ///     );
     ///
-    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
+    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
     ///     matches.get_one::<bool>("flag").copied(),
@@ -123,7 +131,7 @@ pub enum ArgAction {
     ///             )
     ///     );
     ///
-    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
+    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
     ///     matches.get_one::<usize>("flag").copied(),
@@ -145,6 +153,10 @@ pub enum ArgAction {
     /// No value is allowed. To optionally accept a value, see
     /// [`Arg::default_missing_value`][super::Arg::default_missing_value]
     ///
+    /// **NOTE:** If the argument has previously been seen, it will result in a
+    /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless
+    /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set.
+    ///
     /// # Examples
     ///
     /// ```rust
diff --git a/src/builder/app_settings.rs b/src/builder/app_settings.rs
index 8fcad37e..7a9ff8c6 100644
--- a/src/builder/app_settings.rs
+++ b/src/builder/app_settings.rs
@@ -31,6 +31,7 @@ pub(crate) enum AppSettings {
     IgnoreErrors,
     AllowHyphenValues,
     AllowNegativeNumbers,
+    AllArgsOverrideSelf,
     AllowMissingPositional,
     TrailingVarArg,
     DontDelimitTrailingValues,
@@ -93,6 +94,7 @@ bitflags! {
         const VALID_ARG_FOUND                = 1 << 35;
         const INFER_SUBCOMMANDS              = 1 << 36;
         const CONTAINS_LAST                  = 1 << 37;
+        const ARGS_OVERRIDE_SELF             = 1 << 38;
         const HELP_REQUIRED                  = 1 << 39;
         const SUBCOMMAND_PRECEDENCE_OVER_ARG = 1 << 40;
         const DISABLE_HELP_FLAG              = 1 << 41;
@@ -163,6 +165,8 @@ impl_settings! { AppSettings, AppFlags,
         => Flags::BIN_NAME_BUILT,
     InferSubcommands
         => Flags::INFER_SUBCOMMANDS,
+    AllArgsOverrideSelf
+        => Flags::ARGS_OVERRIDE_SELF,
     InferLongArgs
         => Flags::INFER_LONG_ARGS
 }
diff --git a/src/builder/command.rs b/src/builder/command.rs
index 3f6f2489..d685295f 100644
--- a/src/builder/command.rs
+++ b/src/builder/command.rs
@@ -822,7 +822,7 @@ impl Command {
         let mut styled = StyledStr::new();
         let usage = Usage::new(self);
         write_help(&mut styled, self, &usage, false);
-        ok!(write!(w, "{}", styled));
+        write!(w, "{}", styled)?;
         w.flush()
     }
 
@@ -837,7 +837,7 @@ impl Command {
         let mut styled = StyledStr::new();
         let usage = Usage::new(self);
         write_help(&mut styled, self, &usage, true);
-        ok!(write!(w, "{}", styled));
+        write!(w, "{}", styled)?;
         w.flush()
     }
 
@@ -978,6 +978,23 @@ impl Command {
         }
     }
 
+    /// Specifies that all arguments override themselves.
+    ///
+    /// This is the equivalent to saying the `foo` arg using [`Arg::overrides_with("foo")`] for all
+    /// defined arguments.
+    ///
+    /// **NOTE:** This choice is propagated to all child subcommands.
+    ///
+    /// [`Arg::overrides_with("foo")`]: crate::Arg::overrides_with()
+    #[inline]
+    pub fn args_override_self(self, yes: bool) -> Self {
+        if yes {
+            self.global_setting(AppSettings::AllArgsOverrideSelf)
+        } else {
+            self.unset_global_setting(AppSettings::AllArgsOverrideSelf)
+        }
+    }
+
     /// Disables the automatic delimiting of values after `--` or when [`Command::trailing_var_arg`]
     /// was used.
     ///
@@ -3671,6 +3688,11 @@ impl Command {
         self.is_set(AppSettings::ArgsNegateSubcommands)
     }
 
+    #[doc(hidden)]
+    pub fn is_args_override_self(&self) -> bool {
+        self.is_set(AppSettings::AllArgsOverrideSelf)
+    }
+
     /// Report whether [`Command::subcommand_precedence_over_arg`] is set
     pub fn is_subcommand_precedence_over_arg_set(&self) -> bool {
         self.is_set(AppSettings::SubcommandPrecedenceOverArg)
@@ -3896,7 +3918,7 @@ impl Command {
         }
         let is_multicall_set = self.is_multicall_set();
 
-        let sc = some!(self.subcommands.iter_mut().find(|s| s.name == name));
+        let sc = self.subcommands.iter_mut().find(|s| s.name == name)?;
 
         // Display subcommand name, short and long in usage
         let mut sc_names = String::new();
diff --git a/src/builder/range.rs b/src/builder/range.rs
index cc2890b8..16df868a 100644
--- a/src/builder/range.rs
+++ b/src/builder/range.rs
@@ -172,10 +172,10 @@ impl From<std::ops::RangeToInclusive<usize>> for ValueRange {
 
 impl std::fmt::Display for ValueRange {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        ok!(self.start_inclusive.fmt(f));
+        self.start_inclusive.fmt(f)?;
         if !self.is_fixed() {
-            ok!("..=".fmt(f));
-            ok!(self.end_inclusive.fmt(f));
+            "..=".fmt(f)?;
+            self.end_inclusive.fmt(f)?;
         }
         Ok(())
     }
diff --git a/src/builder/styled_str.rs b/src/builder/styled_str.rs
index 6ecd42e1..b127f0e5 100644
--- a/src/builder/styled_str.rs
+++ b/src/builder/styled_str.rs
@@ -223,9 +223,9 @@ impl StyledStr {
                 None => {}
             }
 
-            ok!(buffer.set_color(&color));
-            ok!(buffer.write_all(content.as_bytes()));
-            ok!(buffer.reset());
+            buffer.set_color(&color)?;
+            buffer.write_all(content.as_bytes())?;
+            buffer.reset()?;
         }
 
         Ok(())
@@ -291,7 +291,7 @@ fn cmp_key(c: (Option<Style>, &str)) -> (Option<usize>, &str) {
 impl std::fmt::Display for StyledStr {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         for (_, content) in self.iter() {
-            ok!(std::fmt::Display::fmt(content, f));
+            std::fmt::Display::fmt(content, f)?;
         }
 
         Ok(())
@@ -307,13 +307,12 @@ struct AnsiDisplay<'s> {
 impl std::fmt::Display for AnsiDisplay<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         let mut buffer = termcolor::Buffer::ansi();
-        ok!(self
-            .styled
+        self.styled
             .write_colored(&mut buffer)
-            .map_err(|_| std::fmt::Error));
+            .map_err(|_| std::fmt::Error)?;
         let buffer = buffer.into_inner();
-        let buffer = ok!(String::from_utf8(buffer).map_err(|_| std::fmt::Error));
-        ok!(std::fmt::Display::fmt(&buffer, f));
+        let buffer = String::from_utf8(buffer).map_err(|_| std::fmt::Error)?;
+        std::fmt::Display::fmt(&buffer, f)?;
 
         Ok(())
     }
diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs
index ea0d1d0d..7dcd07e1 100644
--- a/src/builder/value_parser.rs
+++ b/src/builder/value_parser.rs
@@ -569,7 +569,7 @@ where
         arg: Option<&crate::Arg>,
         value: &std::ffi::OsStr,
     ) -> Result<AnyValue, crate::Error> {
-        let value = ok!(TypedValueParser::parse_ref(self, cmd, arg, value));
+        let value = TypedValueParser::parse_ref(self, cmd, arg, value)?;
         Ok(AnyValue::new(value))
     }
 
@@ -579,7 +579,7 @@ where
         arg: Option<&crate::Arg>,
         value: std::ffi::OsString,
     ) -> Result<AnyValue, crate::Error> {
-        let value = ok!(TypedValueParser::parse(self, cmd, arg, value));
+        let value = TypedValueParser::parse(self, cmd, arg, value)?;
         Ok(AnyValue::new(value))
     }
 
@@ -657,7 +657,7 @@ pub trait TypedValueParser: Clone + Send + Sync + 'static {
     ///             )
     ///     );
     ///
-    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
+    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
     ///     matches.get_one::<usize>("flag").copied(),
@@ -694,18 +694,18 @@ where
         arg: Option<&crate::Arg>,
         value: &std::ffi::OsStr,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(value.to_str().ok_or_else(|| {
+        let value = value.to_str().ok_or_else(|| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
-        let value = ok!((self)(value).map_err(|e| {
+        })?;
+        let value = (self)(value).map_err(|e| {
             let arg = arg
                 .map(|a| a.to_string())
                 .unwrap_or_else(|| "...".to_owned());
             crate::Error::value_validation(arg, value.to_owned(), e.into()).with_cmd(cmd)
-        }));
+        })?;
         Ok(value)
     }
 }
@@ -742,12 +742,12 @@ impl TypedValueParser for StringValueParser {
         _arg: Option<&crate::Arg>,
         value: std::ffi::OsString,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(value.into_string().map_err(|_| {
+        let value = value.into_string().map_err(|_| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
+        })?;
         Ok(value)
     }
 }
@@ -939,7 +939,7 @@ impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> TypedValueParser for E
                 .collect::<Vec<_>>()
         };
 
-        let value = ok!(value.to_str().ok_or_else(|| {
+        let value = value.to_str().ok_or_else(|| {
             crate::Error::invalid_value(
                 cmd,
                 value.to_string_lossy().into_owned(),
@@ -947,8 +947,8 @@ impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> TypedValueParser for E
                 arg.map(ToString::to_string)
                     .unwrap_or_else(|| "...".to_owned()),
             )
-        }));
-        let value = ok!(E::value_variants()
+        })?;
+        let value = E::value_variants()
             .iter()
             .find(|v| {
                 v.to_possible_value()
@@ -963,7 +963,7 @@ impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> TypedValueParser for E
                 arg.map(ToString::to_string)
                     .unwrap_or_else(|| "...".to_owned()),
             )
-            }))
+            })?
             .clone();
         Ok(value)
     }
@@ -1049,12 +1049,12 @@ impl TypedValueParser for PossibleValuesParser {
         arg: Option<&crate::Arg>,
         value: std::ffi::OsString,
     ) -> Result<String, crate::Error> {
-        let value = ok!(value.into_string().map_err(|_| {
+        let value = value.into_string().map_err(|_| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
+        })?;
 
         let ignore_case = arg.map(|a| a.is_ignore_case_set()).unwrap_or(false);
         if self.0.iter().any(|v| v.matches(&value, ignore_case)) {
@@ -1233,13 +1233,13 @@ where
         arg: Option<&crate::Arg>,
         raw_value: &std::ffi::OsStr,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(raw_value.to_str().ok_or_else(|| {
+        let value = raw_value.to_str().ok_or_else(|| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
-        let value = ok!(value.parse::<i64>().map_err(|err| {
+        })?;
+        let value = value.parse::<i64>().map_err(|err| {
             let arg = arg
                 .map(|a| a.to_string())
                 .unwrap_or_else(|| "...".to_owned());
@@ -1249,7 +1249,7 @@ where
                 err.into(),
             )
             .with_cmd(cmd)
-        }));
+        })?;
         if !self.bounds.contains(&value) {
             let arg = arg
                 .map(|a| a.to_string())
@@ -1263,7 +1263,7 @@ where
         }
 
         let value: Result<Self::Value, _> = value.try_into();
-        let value = ok!(value.map_err(|err| {
+        let value = value.map_err(|err| {
             let arg = arg
                 .map(|a| a.to_string())
                 .unwrap_or_else(|| "...".to_owned());
@@ -1273,7 +1273,7 @@ where
                 err.into(),
             )
             .with_cmd(cmd)
-        }));
+        })?;
 
         Ok(value)
     }
@@ -1431,13 +1431,13 @@ where
         arg: Option<&crate::Arg>,
         raw_value: &std::ffi::OsStr,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(raw_value.to_str().ok_or_else(|| {
+        let value = raw_value.to_str().ok_or_else(|| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
-        let value = ok!(value.parse::<u64>().map_err(|err| {
+        })?;
+        let value = value.parse::<u64>().map_err(|err| {
             let arg = arg
                 .map(|a| a.to_string())
                 .unwrap_or_else(|| "...".to_owned());
@@ -1447,7 +1447,7 @@ where
                 err.into(),
             )
             .with_cmd(cmd)
-        }));
+        })?;
         if !self.bounds.contains(&value) {
             let arg = arg
                 .map(|a| a.to_string())
@@ -1461,7 +1461,7 @@ where
         }
 
         let value: Result<Self::Value, _> = value.try_into();
-        let value = ok!(value.map_err(|err| {
+        let value = value.map_err(|err| {
             let arg = arg
                 .map(|a| a.to_string())
                 .unwrap_or_else(|| "...".to_owned());
@@ -1471,7 +1471,7 @@ where
                 err.into(),
             )
             .with_cmd(cmd)
-        }));
+        })?;
 
         Ok(value)
     }
@@ -1622,12 +1622,12 @@ impl TypedValueParser for FalseyValueParser {
         _arg: Option<&crate::Arg>,
         value: &std::ffi::OsStr,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(value.to_str().ok_or_else(|| {
+        let value = value.to_str().ok_or_else(|| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
+        })?;
         let value = if value.is_empty() {
             false
         } else {
@@ -1719,19 +1719,19 @@ impl TypedValueParser for BoolishValueParser {
         arg: Option<&crate::Arg>,
         value: &std::ffi::OsStr,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(value.to_str().ok_or_else(|| {
+        let value = value.to_str().ok_or_else(|| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
-        let value = ok!(crate::util::str_to_bool(value).ok_or_else(|| {
+        })?;
+        let value = crate::util::str_to_bool(value).ok_or_else(|| {
             let arg = arg
                 .map(|a| a.to_string())
                 .unwrap_or_else(|| "...".to_owned());
             crate::Error::value_validation(arg, value.to_owned(), "value was not a boolean".into())
                 .with_cmd(cmd)
-        }));
+        })?;
         Ok(value)
     }
 
@@ -1808,12 +1808,12 @@ impl TypedValueParser for NonEmptyStringValueParser {
                     .unwrap_or_else(|| "...".to_owned()),
             ));
         }
-        let value = ok!(value.to_str().ok_or_else(|| {
+        let value = value.to_str().ok_or_else(|| {
             crate::Error::invalid_utf8(
                 cmd,
                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
             )
-        }));
+        })?;
         Ok(value.to_owned())
     }
 }
@@ -1860,7 +1860,7 @@ where
         arg: Option<&crate::Arg>,
         value: &std::ffi::OsStr,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(self.parser.parse_ref(cmd, arg, value));
+        let value = self.parser.parse_ref(cmd, arg, value)?;
         let value = (self.func)(value);
         Ok(value)
     }
@@ -1871,7 +1871,7 @@ where
         arg: Option<&crate::Arg>,
         value: std::ffi::OsString,
     ) -> Result<Self::Value, crate::Error> {
-        let value = ok!(self.parser.parse(cmd, arg, value));
+        let value = self.parser.parse(cmd, arg, value)?;
         let value = (self.func)(value);
         Ok(value)
     }
diff --git a/src/derive.rs b/src/derive.rs
index 74629015..9c62c4f1 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -94,7 +94,7 @@ pub trait Parser: FromArgMatches + CommandFactory + Sized {
 
     /// Parse from `std::env::args_os()`, return Err on error.
     fn try_parse() -> Result<Self, Error> {
-        let mut matches = ok!(<Self as CommandFactory>::command().try_get_matches());
+        let mut matches = <Self as CommandFactory>::command().try_get_matches()?;
         <Self as FromArgMatches>::from_arg_matches_mut(&mut matches).map_err(format_error::<Self>)
     }
 
@@ -123,7 +123,7 @@ pub trait Parser: FromArgMatches + CommandFactory + Sized {
         I: IntoIterator<Item = T>,
         T: Into<OsString> + Clone,
     {
-        let mut matches = ok!(<Self as CommandFactory>::command().try_get_matches_from(itr));
+        let mut matches = <Self as CommandFactory>::command().try_get_matches_from(itr)?;
         <Self as FromArgMatches>::from_arg_matches_mut(&mut matches).map_err(format_error::<Self>)
     }
 
@@ -150,7 +150,7 @@ pub trait Parser: FromArgMatches + CommandFactory + Sized {
         T: Into<OsString> + Clone,
     {
         let mut matches =
-            ok!(<Self as CommandFactory>::command_for_update().try_get_matches_from(itr));
+            <Self as CommandFactory>::command_for_update().try_get_matches_from(itr)?;
         <Self as FromArgMatches>::update_from_arg_matches_mut(self, &mut matches)
             .map_err(format_error::<Self>)
     }
diff --git a/src/error/mod.rs b/src/error/mod.rs
index 12622924..58a409f8 100644
--- a/src/error/mod.rs
+++ b/src/error/mod.rs
@@ -694,11 +694,11 @@ impl<F: ErrorFormatter> error::Error for Error<F> {
 impl<F: ErrorFormatter> Display for Error<F> {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         // Assuming `self.message` already has a trailing newline, from `try_help` or similar
-        ok!(write!(f, "{}", self.formatted()));
+        write!(f, "{}", self.formatted())?;
         if let Some(backtrace) = self.inner.backtrace.as_ref() {
-            ok!(writeln!(f));
-            ok!(writeln!(f, "Backtrace:"));
-            ok!(writeln!(f, "{}", backtrace));
+            writeln!(f)?;
+            writeln!(f, "Backtrace:")?;
+            writeln!(f, "{}", backtrace)?;
         }
         Ok(())
     }
diff --git a/src/macros.rs b/src/macros.rs
index df0680ff..7c9acce1 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -661,25 +661,3 @@ macro_rules! debug {
 macro_rules! debug {
     ($($arg:tt)*) => {};
 }
-
-macro_rules! ok {
-    ($expr:expr) => {
-        match $expr {
-            Ok(val) => val,
-            Err(err) => {
-                return Err(err);
-            }
-        }
-    };
-}
-
-macro_rules! some {
-    ($expr:expr) => {
-        match $expr {
-            Some(val) => val,
-            None => {
-                return None;
-            }
-        }
-    };
-}
diff --git a/src/output/fmt.rs b/src/output/fmt.rs
index 8c102a69..ad0c22e6 100644
--- a/src/output/fmt.rs
+++ b/src/output/fmt.rs
@@ -48,7 +48,7 @@ impl Colorizer {
         };
 
         let mut buffer = writer.buffer();
-        ok!(self.content.write_colored(&mut buffer));
+        self.content.write_colored(&mut buffer)?;
         writer.print(&buffer)
     }
 
diff --git a/src/output/help_template.rs b/src/output/help_template.rs
index bc0df49e..00516bc5 100644
--- a/src/output/help_template.rs
+++ b/src/output/help_template.rs
@@ -987,9 +987,7 @@ pub(crate) fn dimensions() -> (Option<usize>, Option<usize>) {
 
 #[cfg(feature = "wrap_help")]
 fn parse_env(var: &str) -> Option<usize> {
-    some!(some!(std::env::var_os(var)).to_str())
-        .parse::<usize>()
-        .ok()
+    std::env::var_os(var)?.to_str()?.parse::<usize>().ok()
 }
 
 fn should_show_arg(use_long: bool, arg: &Arg) -> bool {
diff --git a/src/output/usage.rs b/src/output/usage.rs
index aa23c9ce..4e7cf3ba 100644
--- a/src/output/usage.rs
+++ b/src/output/usage.rs
@@ -35,7 +35,7 @@ impl<'cmd> Usage<'cmd> {
     // any subcommands have been parsed (so as to give subcommands their own usage recursively)
     pub(crate) fn create_usage_with_title(&self, used: &[Id]) -> Option<StyledStr> {
         debug!("Usage::create_usage_with_title");
-        let usage = some!(self.create_usage_no_title(used));
+        let usage = self.create_usage_no_title(used)?;
 
         let mut styled = StyledStr::new();
         styled.header("Usage:");
diff --git a/src/parser/arg_matcher.rs b/src/parser/arg_matcher.rs
index 071e3b27..3eac897f 100644
--- a/src/parser/arg_matcher.rs
+++ b/src/parser/arg_matcher.rs
@@ -101,8 +101,8 @@ impl ArgMatcher {
         self.matches.args.get_mut(arg)
     }
 
-    pub(crate) fn remove(&mut self, arg: &Id) {
-        self.matches.args.remove(arg);
+    pub(crate) fn remove(&mut self, arg: &Id) -> bool {
+        self.matches.args.remove(arg).is_some()
     }
 
     pub(crate) fn contains(&self, arg: &Id) -> bool {
diff --git a/src/parser/features/suggestions.rs b/src/parser/features/suggestions.rs
index f0d47709..a64d3c30 100644
--- a/src/parser/features/suggestions.rs
+++ b/src/parser/features/suggestions.rs
@@ -63,8 +63,8 @@ where
 
                 let subcommand_name = subcommand.get_name();
 
-                let candidate = some!(did_you_mean(arg, longs).pop());
-                let score = some!(remaining_args.iter().position(|x| subcommand_name == *x));
+                let candidate = did_you_mean(arg, longs).pop()?;
+                let score = remaining_args.iter().position(|x| subcommand_name == *x)?;
                 Some((score, (candidate, Some(subcommand_name.to_string()))))
             })
             .min_by_key(|(x, _)| *x)
diff --git a/src/parser/matches/any_value.rs b/src/parser/matches/any_value.rs
index dc7a3e95..a9277e75 100644
--- a/src/parser/matches/any_value.rs
+++ b/src/parser/matches/any_value.rs
@@ -22,7 +22,7 @@ impl AnyValue {
     pub(crate) fn downcast_into<T: std::any::Any + Clone + Send + Sync>(self) -> Result<T, Self> {
         let id = self.id;
         let value =
-            ok!(std::sync::Arc::downcast::<T>(self.inner).map_err(|inner| Self { inner, id }));
+            std::sync::Arc::downcast::<T>(self.inner).map_err(|inner| Self { inner, id })?;
         let value = std::sync::Arc::try_unwrap(value).unwrap_or_else(|arc| (*arc).clone());
         Ok(value)
     }
diff --git a/src/parser/matches/arg_matches.rs b/src/parser/matches/arg_matches.rs
index bc900499..bcebb1fe 100644
--- a/src/parser/matches/arg_matches.rs
+++ b/src/parser/matches/arg_matches.rs
@@ -162,7 +162,7 @@ impl ArgMatches {
     ///             .action(clap::ArgAction::SetTrue)
     ///     );
     ///
-    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
+    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
     ///     matches.get_flag("flag"),
@@ -454,7 +454,7 @@ impl ArgMatches {
     #[cfg(feature = "unstable-grouped")]
     #[cfg_attr(debug_assertions, track_caller)]
     pub fn grouped_values_of(&self, id: &str) -> Option<GroupedValues> {
-        let arg = some!(self.get_arg(id));
+        let arg = self.get_arg(id)?;
         let v = GroupedValues {
             iter: arg.vals().map(|g| g.iter().map(unwrap_string).collect()),
             len: arg.vals().len(),
@@ -636,8 +636,8 @@ impl ArgMatches {
     /// [delimiter]: crate::Arg::value_delimiter()
     #[cfg_attr(debug_assertions, track_caller)]
     pub fn index_of(&self, id: &str) -> Option<usize> {
-        let arg = some!(self.get_arg(id));
-        let i = some!(arg.get_index(0));
+        let arg = self.get_arg(id)?;
+        let i = arg.get_index(0)?;
         Some(i)
     }
 
@@ -718,7 +718,7 @@ impl ArgMatches {
     /// [delimiter]: Arg::value_delimiter()
     #[cfg_attr(debug_assertions, track_caller)]
     pub fn indices_of(&self, id: &str) -> Option<Indices<'_>> {
-        let arg = some!(self.get_arg(id));
+        let arg = self.get_arg(id)?;
         let i = Indices {
             iter: arg.indices(),
             len: arg.num_vals(),
@@ -941,7 +941,7 @@ impl ArgMatches {
         &self,
         id: &str,
     ) -> Result<Option<&T>, MatchesError> {
-        let arg = ok!(self.try_get_arg_t::<T>(id));
+        let arg = self.try_get_arg_t::<T>(id)?;
         let value = match arg.and_then(|a| a.first()) {
             Some(value) => value,
             None => {
@@ -959,7 +959,7 @@ impl ArgMatches {
         &self,
         id: &str,
     ) -> Result<Option<ValuesRef<T>>, MatchesError> {
-        let arg = match ok!(self.try_get_arg_t::<T>(id)) {
+        let arg = match self.try_get_arg_t::<T>(id)? {
             Some(arg) => arg,
             None => return Ok(None),
         };
@@ -975,7 +975,7 @@ impl ArgMatches {
 
     /// Non-panicking version of [`ArgMatches::get_raw`]
     pub fn try_get_raw(&self, id: &str) -> Result<Option<RawValues<'_>>, MatchesError> {
-        let arg = match ok!(self.try_get_arg(id)) {
+        let arg = match self.try_get_arg(id)? {
             Some(arg) => arg,
             None => return Ok(None),
         };
@@ -993,7 +993,7 @@ impl ArgMatches {
         &mut self,
         id: &str,
     ) -> Result<Option<T>, MatchesError> {
-        match ok!(self.try_remove_arg_t::<T>(id)) {
+        match self.try_remove_arg_t::<T>(id)? {
             Some(values) => Ok(values
                 .into_vals_flatten()
                 // enforced by `try_get_arg_t`
@@ -1008,7 +1008,7 @@ impl ArgMatches {
         &mut self,
         id: &str,
     ) -> Result<Option<Values<T>>, MatchesError> {
-        let arg = match ok!(self.try_remove_arg_t::<T>(id)) {
+        let arg = match self.try_remove_arg_t::<T>(id)? {
             Some(arg) => arg,
             None => return Ok(None),
         };
@@ -1024,7 +1024,7 @@ impl ArgMatches {
 
     /// Non-panicking version of [`ArgMatches::contains_id`]
     pub fn try_contains_id(&self, id: &str) -> Result<bool, MatchesError> {
-        ok!(self.verify_arg(id));
+        self.verify_arg(id)?;
 
         let presence = self.args.contains_key(id);
         Ok(presence)
@@ -1035,7 +1035,7 @@ impl ArgMatches {
 impl ArgMatches {
     #[inline]
     fn try_get_arg(&self, arg: &str) -> Result<Option<&MatchedArg>, MatchesError> {
-        ok!(self.verify_arg(arg));
+        self.verify_arg(arg)?;
         Ok(self.args.get(arg))
     }
 
@@ -1044,13 +1044,13 @@ impl ArgMatches {
         &self,
         arg: &str,
     ) -> Result<Option<&MatchedArg>, MatchesError> {
-        let arg = match ok!(self.try_get_arg(arg)) {
+        let arg = match self.try_get_arg(arg)? {
             Some(arg) => arg,
             None => {
                 return Ok(None);
             }
         };
-        ok!(self.verify_arg_t::<T>(arg));
+        self.verify_arg_t::<T>(arg)?;
         Ok(Some(arg))
     }
 
@@ -1059,7 +1059,7 @@ impl ArgMatches {
         &mut self,
         arg: &str,
     ) -> Result<Option<MatchedArg>, MatchesError> {
-        ok!(self.verify_arg(arg));
+        self.verify_arg(arg)?;
         let (id, matched) = match self.args.remove_entry(arg) {
             Some((id, matched)) => (id, matched),
             None => {
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
index 4a90f003..c493630f 100644
--- a/src/parser/parser.rs
+++ b/src/parser/parser.rs
@@ -108,7 +108,7 @@ impl<'cmd> Parser<'cmd> {
                     debug!("Parser::get_matches_with: sc={:?}", sc_name);
                     if let Some(sc_name) = sc_name {
                         if sc_name == "help" && !self.cmd.is_disable_help_subcommand_set() {
-                            ok!(self.parse_help_subcommand(raw_args.remaining(&mut args_cursor)));
+                            self.parse_help_subcommand(raw_args.remaining(&mut args_cursor))?;
                             unreachable!("`parse_help_subcommand` always errors");
                         } else {
                             subcmd_name = Some(sc_name.to_owned());
@@ -129,14 +129,14 @@ impl<'cmd> Parser<'cmd> {
                         continue;
                     }
                 } else if let Some((long_arg, long_value)) = arg_os.to_long() {
-                    let parse_result = ok!(self.parse_long_arg(
+                    let parse_result = self.parse_long_arg(
                         matcher,
                         long_arg,
                         long_value,
                         &parse_state,
                         pos_counter,
                         &mut valid_arg_found,
-                    ));
+                    )?;
                     debug!(
                         "Parser::get_matches_with: After parse_long_arg {:?}",
                         parse_result
@@ -199,13 +199,13 @@ impl<'cmd> Parser<'cmd> {
                     // Try to parse short args like normal, if allow_hyphen_values or
                     // AllowNegativeNumbers is set, parse_short_arg will *not* throw
                     // an error, and instead return Ok(None)
-                    let parse_result = ok!(self.parse_short_arg(
+                    let parse_result = self.parse_short_arg(
                         matcher,
                         short_arg,
                         &parse_state,
                         pos_counter,
                         &mut valid_arg_found,
-                    ));
+                    )?;
                     // If it's None, we then check if one of those two AppSettings was set
                     debug!(
                         "Parser::get_matches_with: After parse_short_arg {:?}",
@@ -388,7 +388,7 @@ impl<'cmd> Parser<'cmd> {
                 }
 
                 if matcher.pending_arg_id() != Some(&arg.id) || !arg.is_multiple_values_set() {
-                    ok!(self.resolve_pending(matcher));
+                    self.resolve_pending(matcher)?;
                 }
                 if let Some(_parse_result) = self.check_terminator(arg, arg_os.to_value_os()) {
                     debug!(
@@ -432,7 +432,7 @@ impl<'cmd> Parser<'cmd> {
                 sc_m.start_occurrence_of_external(self.cmd);
 
                 for raw_val in raw_args.remaining(&mut args_cursor) {
-                    let val = ok!(external_parser.parse_ref(self.cmd, None, raw_val));
+                    let val = external_parser.parse_ref(self.cmd, None, raw_val)?;
                     let external_id = Id::from_static_ref(Id::EXTERNAL);
                     sc_m.add_val_to(&external_id, val, raw_val.to_os_string());
                 }
@@ -442,10 +442,10 @@ impl<'cmd> Parser<'cmd> {
                     matches: sc_m.into_inner(),
                 });
 
-                ok!(self.resolve_pending(matcher));
+                self.resolve_pending(matcher)?;
                 #[cfg(feature = "env")]
-                ok!(self.add_env(matcher));
-                ok!(self.add_defaults(matcher));
+                self.add_env(matcher)?;
+                self.add_defaults(matcher)?;
                 return Validator::new(self.cmd).validate(parse_state, matcher);
             } else {
                 // Start error processing
@@ -461,13 +461,13 @@ impl<'cmd> Parser<'cmd> {
                 .expect(INTERNAL_ERROR_MSG)
                 .get_name()
                 .to_owned();
-            ok!(self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor, keep_state));
+            self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor, keep_state)?;
         }
 
-        ok!(self.resolve_pending(matcher));
+        self.resolve_pending(matcher)?;
         #[cfg(feature = "env")]
-        ok!(self.add_env(matcher));
-        ok!(self.add_defaults(matcher));
+        self.add_env(matcher)?;
+        self.add_defaults(matcher)?;
         Validator::new(self.cmd).validate(parse_state, matcher)
     }
 
@@ -540,7 +540,7 @@ impl<'cmd> Parser<'cmd> {
         valid_arg_found: bool,
     ) -> Option<&str> {
         debug!("Parser::possible_subcommand: arg={:?}", arg);
-        let arg = some!(arg.ok());
+        let arg = arg.ok()?;
 
         if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) {
             if self.cmd.is_infer_subcommands_set() {
@@ -910,14 +910,14 @@ impl<'cmd> Parser<'cmd> {
                 if !arg.is_takes_value_set() {
                     let arg_values = Vec::new();
                     let trailing_idx = None;
-                    ret = ok!(self.react(
+                    ret = self.react(
                         Some(ident),
                         ValueSource::CommandLine,
                         arg,
                         arg_values,
                         trailing_idx,
                         matcher,
-                    ));
+                    )?;
                     continue;
                 }
 
@@ -943,7 +943,7 @@ impl<'cmd> Parser<'cmd> {
                 } else {
                     (val, false)
                 };
-                match ok!(self.parse_opt_value(ident, val, arg, matcher, has_eq)) {
+                match self.parse_opt_value(ident, val, arg, matcher, has_eq)? {
                     ParseResult::AttachedValueNotConsumed => continue,
                     x => return Ok(x),
                 }
@@ -952,7 +952,7 @@ impl<'cmd> Parser<'cmd> {
             return if let Some(sc_name) = self.cmd.find_short_subcmd(c) {
                 debug!("Parser::parse_short_arg:iter:{}: subcommand={}", c, sc_name);
                 // Make sure indices get updated before reading `self.cur_idx`
-                ok!(self.resolve_pending(matcher));
+                self.resolve_pending(matcher)?;
                 self.cur_idx.set(self.cur_idx.get() + 1);
                 debug!("Parser::parse_short_arg: cur_idx:={}", self.cur_idx.get());
 
@@ -999,14 +999,14 @@ impl<'cmd> Parser<'cmd> {
                 debug!("Requires equals, but min_vals == 0");
                 let arg_values = Vec::new();
                 let trailing_idx = None;
-                let react_result = ok!(self.react(
+                let react_result = self.react(
                     Some(ident),
                     ValueSource::CommandLine,
                     arg,
                     arg_values,
                     trailing_idx,
                     matcher,
-                ));
+                )?;
                 debug_assert_eq!(react_result, ParseResult::ValuesDone);
                 if attached_value.is_some() {
                     Ok(ParseResult::AttachedValueNotConsumed)
@@ -1022,20 +1022,20 @@ impl<'cmd> Parser<'cmd> {
         } else if let Some(v) = attached_value {
             let arg_values = vec![v.to_os_str().into_owned()];
             let trailing_idx = None;
-            let react_result = ok!(self.react(
+            let react_result = self.react(
                 Some(ident),
                 ValueSource::CommandLine,
                 arg,
                 arg_values,
                 trailing_idx,
                 matcher,
-            ));
+            )?;
             debug_assert_eq!(react_result, ParseResult::ValuesDone);
             // Attached are always done
             Ok(ParseResult::ValuesDone)
         } else {
             debug!("Parser::parse_opt_value: More arg vals required...");
-            ok!(self.resolve_pending(matcher));
+            self.resolve_pending(matcher)?;
             let trailing_values = false;
             matcher.pending_values_mut(&arg.id, Some(ident), trailing_values);
             Ok(ParseResult::Opt(arg.id.clone()))
@@ -1072,7 +1072,7 @@ impl<'cmd> Parser<'cmd> {
                 self.cur_idx.get()
             );
             let value_parser = arg.get_value_parser();
-            let val = ok!(value_parser.parse_ref(self.cmd, Some(arg), &raw_val));
+            let val = value_parser.parse_ref(self.cmd, Some(arg), &raw_val)?;
 
             matcher.add_val_to(&arg.id, val, raw_val);
             matcher.add_index_to(&arg.id, self.cur_idx.get());
@@ -1100,14 +1100,14 @@ impl<'cmd> Parser<'cmd> {
 
         debug!("Parser::resolve_pending: id={:?}", pending.id);
         let arg = self.cmd.find(&pending.id).expect(INTERNAL_ERROR_MSG);
-        let _ = ok!(self.react(
+        let _ = self.react(
             pending.ident,
             ValueSource::CommandLine,
             arg,
             pending.raw_vals,
             pending.trailing_idx,
             matcher,
-        ));
+        )?;
 
         Ok(())
     }
@@ -1121,7 +1121,7 @@ impl<'cmd> Parser<'cmd> {
         mut trailing_idx: Option<usize>,
         matcher: &mut ArgMatcher,
     ) -> ClapResult<ParseResult> {
-        ok!(self.resolve_pending(matcher));
+        self.resolve_pending(matcher)?;
 
         debug!(
             "Parser::react action={:?}, identifier={:?}, source={:?}",
@@ -1133,7 +1133,7 @@ impl<'cmd> Parser<'cmd> {
         // Process before `default_missing_values` to avoid it counting as values from the command
         // line
         if source == ValueSource::CommandLine {
-            ok!(self.verify_num_args(arg, &raw_vals));
+            self.verify_num_args(arg, &raw_vals)?;
         }
 
         if raw_vals.is_empty() {
@@ -1179,9 +1179,16 @@ impl<'cmd> Parser<'cmd> {
                     self.cur_idx.set(self.cur_idx.get() + 1);
                     debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
                 }
-                matcher.remove(&arg.id);
+                if matcher.remove(&arg.id) && !self.cmd.is_args_override_self() {
+                    return Err(ClapError::argument_conflict(
+                        self.cmd,
+                        arg.to_string(),
+                        vec![arg.to_string()],
+                        Usage::new(self.cmd).create_usage_with_title(&[]),
+                    ));
+                }
                 self.start_custom_arg(matcher, arg, source);
-                ok!(self.push_arg_values(arg, raw_vals, matcher));
+                self.push_arg_values(arg, raw_vals, matcher)?;
                 if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
                     debug!(
                         "Parser::react not enough values passed in, leaving it to the validator to complain",
@@ -1198,7 +1205,7 @@ impl<'cmd> Parser<'cmd> {
                     debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
                 }
                 self.start_custom_arg(matcher, arg, source);
-                ok!(self.push_arg_values(arg, raw_vals, matcher));
+                self.push_arg_values(arg, raw_vals, matcher)?;
                 if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
                     debug!(
                         "Parser::react not enough values passed in, leaving it to the validator to complain",
@@ -1213,9 +1220,16 @@ impl<'cmd> Parser<'cmd> {
                     raw_vals
                 };
 
-                matcher.remove(&arg.id);
+                if matcher.remove(&arg.id) && !self.cmd.is_args_override_self() {
+                    return Err(ClapError::argument_conflict(
+                        self.cmd,
+                        arg.to_string(),
+                        vec![arg.to_string()],
+                        Usage::new(self.cmd).create_usage_with_title(&[]),
+                    ));
+                }
                 self.start_custom_arg(matcher, arg, source);
-                ok!(self.push_arg_values(arg, raw_vals, matcher));
+                self.push_arg_values(arg, raw_vals, matcher)?;
                 Ok(ParseResult::ValuesDone)
             }
             ArgAction::SetFalse => {
@@ -1225,9 +1239,16 @@ impl<'cmd> Parser<'cmd> {
                     raw_vals
                 };
 
-                matcher.remove(&arg.id);
+                if matcher.remove(&arg.id) && self.cmd.is_args_override_self() {
+                    return Err(ClapError::argument_conflict(
+                        self.cmd,
+                        arg.to_string(),
+                        vec![arg.to_string()],
+                        Usage::new(self.cmd).create_usage_with_title(&[]),
+                    ));
+                }
                 self.start_custom_arg(matcher, arg, source);
-                ok!(self.push_arg_values(arg, raw_vals, matcher));
+                self.push_arg_values(arg, raw_vals, matcher)?;
                 Ok(ParseResult::ValuesDone)
             }
             ArgAction::Count => {
@@ -1243,7 +1264,7 @@ impl<'cmd> Parser<'cmd> {
 
                 matcher.remove(&arg.id);
                 self.start_custom_arg(matcher, arg, source);
-                ok!(self.push_arg_values(arg, raw_vals, matcher));
+                self.push_arg_values(arg, raw_vals, matcher)?;
                 Ok(ParseResult::ValuesDone)
             }
             ArgAction::Help => {
@@ -1366,14 +1387,14 @@ impl<'cmd> Parser<'cmd> {
                 debug!("Parser::add_env: Found an opt with value={:?}", val);
                 let arg_values = vec![val.to_owned()];
                 let trailing_idx = None;
-                let _ = ok!(self.react(
+                let _ = self.react(
                     None,
                     ValueSource::EnvVariable,
                     arg,
                     arg_values,
                     trailing_idx,
                     matcher,
-                ));
+                )?;
             }
         }
 
@@ -1385,7 +1406,7 @@ impl<'cmd> Parser<'cmd> {
 
         for arg in self.cmd.get_arguments() {
             debug!("Parser::add_defaults:iter:{}:", arg.get_id());
-            ok!(self.add_default_value(arg, matcher));
+            self.add_default_value(arg, matcher)?;
         }
 
         Ok(())
@@ -1411,14 +1432,14 @@ impl<'cmd> Parser<'cmd> {
                         if let Some(default) = default {
                             let arg_values = vec![default.to_os_string()];
                             let trailing_idx = None;
-                            let _ = ok!(self.react(
+                            let _ = self.react(
                                 None,
                                 ValueSource::DefaultValue,
                                 arg,
                                 arg_values,
                                 trailing_idx,
                                 matcher,
-                            ));
+                            )?;
                         }
                         return Ok(());
                     }
@@ -1447,14 +1468,14 @@ impl<'cmd> Parser<'cmd> {
                     .map(crate::builder::OsStr::to_os_string)
                     .collect();
                 let trailing_idx = None;
-                let _ = ok!(self.react(
+                let _ = self.react(
                     None,
                     ValueSource::DefaultValue,
                     arg,
                     arg_values,
                     trailing_idx,
                     matcher,
-                ));
+                )?;
             }
         } else {
             debug!(
diff --git a/src/parser/validator.rs b/src/parser/validator.rs
index 49ca1881..de0f9108 100644
--- a/src/parser/validator.rs
+++ b/src/parser/validator.rs
@@ -76,9 +76,9 @@ impl<'cmd> Validator<'cmd> {
             ));
         }
 
-        ok!(self.validate_conflicts(matcher, &mut conflicts));
+        self.validate_conflicts(matcher, &mut conflicts)?;
         if !(self.cmd.is_subcommand_negates_reqs_set() && has_subcmd) {
-            ok!(self.validate_required(matcher, &mut conflicts));
+            self.validate_required(matcher, &mut conflicts)?;
         }
 
         Ok(())
@@ -91,7 +91,7 @@ impl<'cmd> Validator<'cmd> {
     ) -> ClapResult<()> {
         debug!("Validator::validate_conflicts");
 
-        ok!(self.validate_exclusive(matcher));
+        self.validate_exclusive(matcher)?;
 
         for arg_id in matcher
             .arg_ids()
@@ -100,7 +100,7 @@ impl<'cmd> Validator<'cmd> {
         {
             debug!("Validator::validate_conflicts::iter: id={:?}", arg_id);
             let conflicts = conflicts.gather_conflicts(self.cmd, matcher, arg_id);
-            ok!(self.build_conflict_err(arg_id, &conflicts, matcher));
+            self.build_conflict_err(arg_id, &conflicts, matcher)?;
         }
 
         Ok(())
@@ -361,7 +361,7 @@ impl<'cmd> Validator<'cmd> {
         }
 
         if !missing_required.is_empty() {
-            ok!(self.missing_required_error(matcher, missing_required));
+            self.missing_required_error(matcher, missing_required)?;
         }
 
         Ok(())
diff --git a/src/util/flat_map.rs b/src/util/flat_map.rs
index 7d689ab3..ce5b0fb3 100644
--- a/src/util/flat_map.rs
+++ b/src/util/flat_map.rs
@@ -65,11 +65,11 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
         K: Borrow<Q>,
         Q: std::hash::Hash + Eq,
     {
-        let index = some!(self
+        let index = self
             .keys
             .iter()
             .enumerate()
-            .find_map(|(i, k)| (k.borrow() == key).then(|| i)));
+            .find_map(|(i, k)| (k.borrow() == key).then(|| i))?;
         let key = self.keys.remove(index);
         let value = self.values.remove(index);
         Some((key, value))


Test patch:
diff --git a/tests/builder/action.rs b/tests/builder/action.rs
index 6f4bcda2..d9b24873 100644
--- a/tests/builder/action.rs
+++ b/tests/builder/action.rs
@@ -1,6 +1,7 @@
 #![allow(clippy::bool_assert_comparison)]
 
 use clap::builder::ArgPredicate;
+use clap::error::ErrorKind;
 use clap::Arg;
 use clap::ArgAction;
 use clap::Command;
@@ -22,8 +23,15 @@ fn set() {
     assert_eq!(matches.contains_id("mammal"), true);
     assert_eq!(matches.index_of("mammal"), Some(2));
 
+    let result = cmd
+        .clone()
+        .try_get_matches_from(["test", "--mammal", "dog", "--mammal", "cat"]);
+    let err = result.err().unwrap();
+    assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
+
     let matches = cmd
         .clone()
+        .args_override_self(true)
         .try_get_matches_from(["test", "--mammal", "dog", "--mammal", "cat"])
         .unwrap();
     assert_eq!(matches.get_one::<String>("mammal").unwrap(), "cat");
@@ -88,8 +96,15 @@ fn set_true() {
     assert_eq!(matches.contains_id("mammal"), true);
     assert_eq!(matches.index_of("mammal"), Some(1));
 
+    let result = cmd
+        .clone()
+        .try_get_matches_from(["test", "--mammal", "--mammal"]);
+    let err = result.err().unwrap();
+    assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
+
     let matches = cmd
         .clone()
+        .args_override_self(true)
         .try_get_matches_from(["test", "--mammal", "--mammal"])
         .unwrap();
     assert_eq!(*matches.get_one::<bool>("mammal").unwrap(), true);
diff --git a/tests/builder/app_settings.rs b/tests/builder/app_settings.rs
index 723e15d6..c9c8cf5a 100644
--- a/tests/builder/app_settings.rs
+++ b/tests/builder/app_settings.rs
@@ -986,65 +986,11 @@ fn built_in_subcommand_escaped() {
     }
 }
 
-#[test]
-fn aaos_flags() {
-    // flags
-    let cmd = Command::new("posix").arg(arg!(--flag  "some flag").action(ArgAction::SetTrue));
-
-    let res = cmd.clone().try_get_matches_from(vec!["", "--flag"]);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    let m = res.unwrap();
-    assert!(m.contains_id("flag"));
-    assert!(*m.get_one::<bool>("flag").expect("defaulted by clap"));
-
-    let res = cmd.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    let m = res.unwrap();
-    assert!(m.contains_id("flag"));
-    assert!(*m.get_one::<bool>("flag").expect("defaulted by clap"));
-}
-
-#[test]
-fn aaos_flags_mult() {
-    // flags with multiple
-    let cmd = Command::new("posix").arg(arg!(--flag  "some flag").action(ArgAction::Count));
-
-    let res = cmd.clone().try_get_matches_from(vec!["", "--flag"]);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    let m = res.unwrap();
-    assert!(m.contains_id("flag"));
-    assert_eq!(*m.get_one::<u8>("flag").expect("defaulted by clap"), 1);
-
-    let res = cmd.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    let m = res.unwrap();
-    assert!(m.contains_id("flag"));
-    assert_eq!(*m.get_one::<u8>("flag").expect("defaulted by clap"), 4);
-}
-
-#[test]
-fn aaos_opts() {
-    // opts
-    let res = Command::new("posix")
-        .arg(
-            arg!(--opt <val> "some option")
-                .required(true)
-                .action(ArgAction::Set),
-        )
-        .try_get_matches_from(vec!["", "--opt=some", "--opt=other"]);
-    assert!(res.is_ok(), "{}", res.unwrap_err());
-    let m = res.unwrap();
-    assert!(m.contains_id("opt"));
-    assert_eq!(
-        m.get_one::<String>("opt").map(|v| v.as_str()),
-        Some("other")
-    );
-}
-
 #[test]
 fn aaos_opts_w_other_overrides() {
     // opts with other overrides
     let res = Command::new("posix")
+        .args_override_self(true)
         .arg(arg!(--opt <val> "some option").action(ArgAction::Set))
         .arg(
             arg!(--other <val> "some other option")
@@ -1066,6 +1012,7 @@ fn aaos_opts_w_other_overrides() {
 fn aaos_opts_w_other_overrides_rev() {
     // opts with other overrides, rev
     let res = Command::new("posix")
+        .args_override_self(true)
         .arg(
             arg!(--opt <val> "some option")
                 .required(true)
@@ -1092,6 +1039,7 @@ fn aaos_opts_w_other_overrides_rev() {
 fn aaos_opts_w_other_overrides_2() {
     // opts with other overrides
     let res = Command::new("posix")
+        .args_override_self(true)
         .arg(
             arg!(--opt <val> "some option")
                 .overrides_with("other")
@@ -1113,6 +1061,7 @@ fn aaos_opts_w_other_overrides_2() {
 fn aaos_opts_w_other_overrides_rev_2() {
     // opts with other overrides, rev
     let res = Command::new("posix")
+        .args_override_self(true)
         .arg(
             arg!(--opt <val> "some option")
                 .required(true)
@@ -1259,6 +1208,7 @@ fn aaos_pos_mult() {
 #[test]
 fn aaos_option_use_delim_false() {
     let m = Command::new("posix")
+        .args_override_self(true)
         .arg(
             arg!(--opt <val> "some option")
                 .required(true)
diff --git a/tests/builder/flags.rs b/tests/builder/flags.rs
index 0f4d316f..e86adcdf 100644
--- a/tests/builder/flags.rs
+++ b/tests/builder/flags.rs
@@ -19,6 +19,7 @@ fn flag_using_short() {
 #[test]
 fn lots_o_flags_sep() {
     let r = Command::new("opts")
+        .args_override_self(true)
         .arg(arg!(o: -o ... "some flag").action(ArgAction::SetTrue))
         .try_get_matches_from(vec![
             "", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
@@ -53,6 +54,7 @@ fn lots_o_flags_sep() {
 #[test]
 fn lots_o_flags_combined() {
     let r = Command::new("opts")
+        .args_override_self(true)
         .arg(arg!(o: -o ... "some flag").action(ArgAction::SetTrue))
         .try_get_matches_from(vec![
             "",
diff --git a/tests/builder/grouped_values.rs b/tests/builder/grouped_values.rs
index a5336130..67df706e 100644
--- a/tests/builder/grouped_values.rs
+++ b/tests/builder/grouped_values.rs
@@ -223,6 +223,7 @@ fn grouped_interleaved_positional_occurrences() {
 #[test]
 fn issue_2171() {
     let schema = Command::new("ripgrep#1701 reproducer")
+        .args_override_self(true)
         .arg(
             Arg::new("pretty")
                 .short('p')
diff --git a/tests/builder/indices.rs b/tests/builder/indices.rs
index 5f6d40de..dfe7d665 100644
--- a/tests/builder/indices.rs
+++ b/tests/builder/indices.rs
@@ -3,6 +3,7 @@ use clap::{Arg, ArgAction, Command};
 #[test]
 fn indices_mult_opts() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(
             Arg::new("exclude")
                 .short('e')
@@ -32,6 +33,7 @@ fn indices_mult_opts() {
 #[test]
 fn index_mult_opts() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(
             Arg::new("exclude")
                 .short('e')
@@ -55,6 +57,7 @@ fn index_mult_opts() {
 #[test]
 fn index_flag() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue))
         .arg(Arg::new("include").short('i').action(ArgAction::SetTrue))
         .try_get_matches_from(vec!["ind", "-e", "-i"])
@@ -67,6 +70,7 @@ fn index_flag() {
 #[test]
 fn index_flags() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue))
         .arg(Arg::new("include").short('i').action(ArgAction::SetTrue))
         .try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"])
@@ -79,6 +83,7 @@ fn index_flags() {
 #[test]
 fn indices_mult_flags() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue))
         .arg(Arg::new("include").short('i').action(ArgAction::SetTrue))
         .try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"])
@@ -91,6 +96,7 @@ fn indices_mult_flags() {
 #[test]
 fn indices_mult_flags_combined() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue))
         .arg(Arg::new("include").short('i').action(ArgAction::SetTrue))
         .try_get_matches_from(vec!["ind", "-eieei"])
@@ -103,6 +109,7 @@ fn indices_mult_flags_combined() {
 #[test]
 fn indices_mult_flags_opt_combined() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue))
         .arg(Arg::new("include").short('i').action(ArgAction::SetTrue))
         .arg(Arg::new("option").short('o').action(ArgAction::Set))
@@ -117,6 +124,7 @@ fn indices_mult_flags_opt_combined() {
 #[test]
 fn indices_mult_flags_opt_combined_eq() {
     let m = Command::new("ind")
+        .args_override_self(true)
         .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue))
         .arg(Arg::new("include").short('i').action(ArgAction::SetTrue))
         .arg(Arg::new("option").short('o').action(ArgAction::Set))
@@ -131,6 +139,7 @@ fn indices_mult_flags_opt_combined_eq() {
 #[test]
 fn indices_mult_opt_value_delim_eq() {
     let m = Command::new("myapp")
+        .args_override_self(true)
         .arg(
             Arg::new("option")
                 .short('o')
@@ -149,6 +158,7 @@ fn indices_mult_opt_value_delim_eq() {
 #[test]
 fn indices_mult_opt_value_no_delim_eq() {
     let m = Command::new("myapp")
+        .args_override_self(true)
         .arg(
             Arg::new("option")
                 .short('o')
@@ -163,6 +173,7 @@ fn indices_mult_opt_value_no_delim_eq() {
 #[test]
 fn indices_mult_opt_mult_flag() {
     let m = Command::new("myapp")
+        .args_override_self(true)
         .arg(Arg::new("option").short('o').action(ArgAction::Append))
         .arg(Arg::new("flag").short('f').action(ArgAction::SetTrue))
         .try_get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"])
diff --git a/tests/builder/multiple_occurrences.rs b/tests/builder/multiple_occurrences.rs
index 0b3d043a..09e50e62 100644
--- a/tests/builder/multiple_occurrences.rs
+++ b/tests/builder/multiple_occurrences.rs
@@ -3,6 +3,7 @@ use clap::{arg, Arg, ArgAction, Command};
 #[test]
 fn multiple_occurrences_of_flags_long() {
     let m = Command::new("mo_flags_long")
+        .args_override_self(true)
         .arg(arg!(--multflag "allowed multiple flag").action(ArgAction::SetTrue))
         .arg(arg!(--flag "disallowed multiple flag").action(ArgAction::SetTrue))
         .try_get_matches_from(vec!["", "--multflag", "--flag", "--multflag"])
@@ -16,6 +17,7 @@ fn multiple_occurrences_of_flags_long() {
 #[test]
 fn multiple_occurrences_of_flags_short() {
     let m = Command::new("mo_flags_short")
+        .args_override_self(true)
         .arg(arg!(-m --multflag "allowed multiple flag").action(ArgAction::SetTrue))
         .arg(arg!(-f --flag "disallowed multiple flag").action(ArgAction::SetTrue))
         .try_get_matches_from(vec!["", "-m", "-f", "-m"])
diff --git a/tests/builder/multiple_values.rs b/tests/builder/multiple_values.rs
index fffe8162..83eec8b4 100644
--- a/tests/builder/multiple_values.rs
+++ b/tests/builder/multiple_values.rs
@@ -401,7 +401,7 @@ fn option_max_more() {
 
 #[test]
 fn optional_value() {
-    let mut cmd = Command::new("test").arg(
+    let mut cmd = Command::new("test").args_override_self(true).arg(
         Arg::new("port")
             .short('p')
             .value_name("NUM")
diff --git a/tests/derive/flags.rs b/tests/derive/flags.rs
index 16ec2473..63fb216a 100644
--- a/tests/derive/flags.rs
+++ b/tests/derive/flags.rs
@@ -21,6 +21,7 @@ use clap::Parser;
 #[test]
 fn bool_type_is_flag() {
     #[derive(Parser, PartialEq, Eq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, long)]
         alice: bool,
diff --git a/tests/derive/options.rs b/tests/derive/options.rs
index e9049376..d6420ab9 100644
--- a/tests/derive/options.rs
+++ b/tests/derive/options.rs
@@ -21,6 +21,7 @@ use clap::{Parser, Subcommand};
 #[test]
 fn required_option() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, long)]
         arg: i32,
@@ -47,6 +48,7 @@ fn required_option() {
 #[test]
 fn option_with_default() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, default_value = "42")]
         arg: i32,
@@ -65,6 +67,7 @@ fn option_with_default() {
 #[test]
 fn option_with_raw_default() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, default_value = "42")]
         arg: i32,
@@ -94,6 +97,7 @@ fn option_from_str() {
     }
 
     #[derive(Debug, Parser, PartialEq)]
+    #[command(args_override_self = true)]
     struct Opt {
         a: Option<A>,
     }
@@ -119,6 +123,7 @@ fn vec_from_str() {
     }
 
     #[derive(Debug, Parser, PartialEq)]
+    #[command(args_override_self = true)]
     struct Opt {
         a: Vec<A>,
     }
@@ -147,6 +152,7 @@ fn option_vec_from_str() {
     }
 
     #[derive(Debug, Parser, PartialEq)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short)]
         a: Option<Vec<A>>,
@@ -162,6 +168,7 @@ fn option_vec_from_str() {
 #[test]
 fn option_type_is_optional() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short)]
         arg: Option<i32>,
@@ -181,6 +188,7 @@ fn option_type_is_optional() {
 fn required_with_option_type() {
     #[derive(Debug, PartialEq, Eq, Parser)]
     #[command(subcommand_negates_reqs = true)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(required = true)]
         req_str: Option<String>,
@@ -223,6 +231,7 @@ fn ignore_qualified_option_type() {
     }
 
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(value_parser = parser)]
         arg: ::std::option::Option<String>,
@@ -239,6 +248,7 @@ fn ignore_qualified_option_type() {
 #[test]
 fn option_option_type_is_optional_value() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short)]
         #[allow(clippy::option_option)]
@@ -266,6 +276,7 @@ fn option_option_type_is_optional_value() {
 #[test]
 fn option_option_type_help() {
     #[derive(Parser, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(long, value_name = "val")]
         arg: Option<Option<i32>>,
@@ -278,6 +289,7 @@ fn option_option_type_help() {
 #[test]
 fn two_option_option_types() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short)]
         arg: Option<Option<i32>>,
@@ -332,6 +344,7 @@ fn two_option_option_types() {
 #[test]
 fn vec_type_is_multiple_occurrences() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, long)]
         arg: Vec<i32>,
@@ -350,6 +363,7 @@ fn vec_type_is_multiple_occurrences() {
 #[test]
 fn vec_type_with_required() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, long, required = true)]
         arg: Vec<i32>,
@@ -368,6 +382,7 @@ fn vec_type_with_required() {
 #[test]
 fn vec_type_with_multiple_values_only() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, long, num_args(1..))]
         arg: Vec<i32>,
@@ -390,6 +405,7 @@ fn ignore_qualified_vec_type() {
     }
 
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(value_parser = parser)]
         arg: ::std::vec::Vec<String>,
@@ -406,6 +422,7 @@ fn ignore_qualified_vec_type() {
 #[test]
 fn option_vec_type() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short)]
         arg: Option<Vec<i32>>,
@@ -428,6 +445,7 @@ fn option_vec_type() {
 #[test]
 fn option_vec_type_structopt_behavior() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short, long, num_args(0..))]
         arg: Option<Vec<i32>>,
@@ -455,6 +473,7 @@ fn option_vec_type_structopt_behavior() {
 #[test]
 fn two_option_vec_types() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(short)]
         arg: Option<Vec<i32>>,
@@ -496,6 +515,7 @@ fn two_option_vec_types() {
 #[test]
 fn explicit_value_parser() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(long, value_parser = clap::value_parser!(i32))]
         arg: i32,
@@ -509,6 +529,7 @@ fn explicit_value_parser() {
 #[test]
 fn implicit_value_parser() {
     #[derive(Parser, PartialEq, Debug)]
+    #[command(args_override_self = true)]
     struct Opt {
         #[arg(long)]
         arg: i32,