From 839ed2588c403a18b9f9db8cb7940a74f19a280e Mon Sep 17 00:00:00 2001 From: CreepySkeleton Date: Tue, 3 Mar 2020 22:00:35 +0300 Subject: [PATCH] Fix core dump with mutually `requires()` args Fixes #1643 --- src/build/app/mod.rs | 7 +++++++ tests/require.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index 7d73af7d..1b67908d 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -1922,10 +1922,17 @@ impl<'b> App<'b> { } }; + let mut processed = vec![]; let mut r_vec = vec![arg]; let mut args = vec![]; while let Some(a) = r_vec.pop() { + if processed.contains(&a) { + continue; + } + + processed.push(a); + if let Some(arg) = self.find(a) { if let Some(ref reqs) = arg.requires { for r in reqs.iter().filter_map(requires_if_or_not) { diff --git a/tests/require.rs b/tests/require.rs index 0da7bbf9..1589fb92 100644 --- a/tests/require.rs +++ b/tests/require.rs @@ -703,3 +703,30 @@ fn issue_1158_conflicting_requirements_rev() { assert!(res.is_ok()); } + +#[test] +fn issue_1643_args_mutually_require_each_other() { + use clap::*; + + fn main() { + let app = App::new("test") + .arg( + Arg::with_name("relation_id") + .help("The relation id to get the data from") + .long("relation-id") + .short('r') + .takes_value(true) + .requires("remote_unit_name"), + ) + .arg( + Arg::with_name("remote_unit_name") + .help("The name of the remote unit to get data from") + .long("remote-unit") + .short('u') + .takes_value(true) + .requires("relation_id"), + ); + + app.get_matches_from(&["test", "-u", "hello"]); + } +}