-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Please complete the following tasks
- I have searched the discussions
- I have searched the open and rejected issues
Rust Version
rustc 1.90.0 (1159e78c4 2025-09-14)
Clap Version
4.5.53
Minimal reproducible code
repo: https://github.com/mkovaxx/repro-clap-two-varargs
use clap::Parser;
fn main() {
let args = CliWithTwoVarArgs::parse_from(std::env::args());
println!("BEFORE: {:?}", args.before);
println!("AFTER: {:?}", args.after);
}
#[derive(Clone, Debug, Parser)]
pub struct CliWithTwoVarArgs {
#[arg(
value_name = "ARGS_BEFORE",
num_args = 0..,
allow_hyphen_values = true,
help = "Options before `--`",
)]
pub before: Vec<String>,
#[arg(
value_name = "ARGS_AFTER",
last = true,
num_args = 0..,
allow_hyphen_values = true,
help = "Options after `--`",
)]
pub after: Vec<String>,
}
#[cfg(test)]
mod test {
use super::*;
const BIN_NAME: &str = "main";
#[test]
fn parse_some_stuff() {
let args = CliWithTwoVarArgs::parse_from([
BIN_NAME,
"--release",
"--",
"--expand-errors",
"--rlimit=100",
]);
assert_eq!(args.before, vec!["--release".to_owned()]);
assert_eq!(
args.after,
vec!["--expand-errors".to_owned(), "--rlimit=100".to_owned()]
);
}
}Steps to reproduce the bug with the above code
cargo test
Actual Behaviour
All arguments, including the --, are in the before field, and after is empty.
Expected Behaviour
Arguments before the -- marker should be in the before field, and arguments after in the after field.
Additional Context
The expectation above is informed by the output of --help:
Usage: repro-clap-two-varargs [ARGS_BEFORE]... [-- [ARGS_AFTER]...]
Arguments:
[ARGS_BEFORE]... Options before `--`
[ARGS_AFTER]... Options after `--`
Options:
-h, --help Print help
Debug Output
running 1 test
[clap_builder::builder::command]Command::_do_parse
[clap_builder::builder::command]Command::_build: name="repro-clap-two-varargs"
[clap_builder::builder::command]Command::_propagate:repro-clap-two-varargs
[clap_builder::builder::command]Command::_check_help_and_version:repro-clap-two-varargs expand_help_tree=false
[clap_builder::builder::command]Command::long_help_exists
[clap_builder::builder::command]Command::_check_help_and_version: Building default --help
[clap_builder::builder::command]Command::_propagate_global_args:repro-clap-two-varargs
[clap_builder::builder::debug_asserts]Command::_debug_asserts
[clap_builder::builder::debug_asserts]Arg::_debug_asserts:before
[clap_builder::builder::debug_asserts]Arg::_debug_asserts:after
[clap_builder::builder::debug_asserts]Arg::_debug_asserts:help
[clap_builder::builder::debug_asserts]Command::_verify_positionals
[clap_builder::parser::parser]Parser::get_matches_with
[clap_builder::parser::parser]Parser::parse
[clap_builder::parser::parser]Parser::get_matches_with: Begin parsing '"--release"'
[clap_builder::parser::parser]Parser::possible_subcommand: arg=Ok("--release")
[clap_builder::parser::parser]Parser::get_matches_with: sc=None
[clap_builder::parser::parser]Parser::parse_long_arg
[clap_builder::parser::parser]Parser::parse_long_arg: Does it contain '='...
[clap_builder::parser::parser]Parser::possible_long_flag_subcommand: arg="release"
[clap_builder::parser::parser]Parser::parse_long_args: positional at 1 allows hyphens
[clap_builder::parser::parser]Parser::get_matches_with: After parse_long_arg MaybeHyphenValue
[clap_builder::parser::parser]Parser::get_matches_with: Positional counter...1
[clap_builder::parser::parser]Parser::get_matches_with: Low index multiples...false
[clap_builder::parser::parser]Parser::get_matches_with: Begin parsing '"--"'
[clap_builder::parser::parser]Parser::get_matches_with: Positional counter...1
[clap_builder::parser::parser]Parser::get_matches_with: Low index multiples...false
[clap_builder::parser::parser]Parser::get_matches_with: Begin parsing '"--expand-errors"'
[clap_builder::parser::parser]Parser::parse_long_arg
[clap_builder::parser::parser]Parser::parse_long_arg: prior arg accepts hyphenated values
[clap_builder::parser::parser]Parser::get_matches_with: After parse_long_arg MaybeHyphenValue
[clap_builder::parser::parser]Parser::get_matches_with: Positional counter...1
[clap_builder::parser::parser]Parser::get_matches_with: Low index multiples...false
[clap_builder::parser::parser]Parser::get_matches_with: Begin parsing '"--rlimit=100"'
[clap_builder::parser::parser]Parser::parse_long_arg
[clap_builder::parser::parser]Parser::parse_long_arg: prior arg accepts hyphenated values
[clap_builder::parser::parser]Parser::get_matches_with: After parse_long_arg MaybeHyphenValue
[clap_builder::parser::parser]Parser::get_matches_with: Positional counter...1
[clap_builder::parser::parser]Parser::get_matches_with: Low index multiples...false
[clap_builder::parser::parser]Parser::resolve_pending: id="before"
[clap_builder::parser::parser]Parser::react action=Append, identifier=Some(Index), source=CommandLine
[clap_builder::parser::parser]Parser::remove_overrides: id="before"
[clap_builder::parser::arg_matcher]ArgMatcher::start_custom_arg: id="before", source=CommandLine
[clap_builder::builder::command]Command::groups_for_arg: id="before"
[clap_builder::parser::arg_matcher]ArgMatcher::start_custom_arg: id="CliWithTwoVarArgs", source=CommandLine
[clap_builder::parser::parser]Parser::push_arg_values: ["--release", "--", "--expand-errors", "--rlimit=100"]
[clap_builder::parser::parser]Parser::add_single_val_to_arg: cur_idx:=1
[clap_builder::parser::parser]Parser::add_single_val_to_arg: cur_idx:=2
[clap_builder::parser::parser]Parser::add_single_val_to_arg: cur_idx:=3
[clap_builder::parser::parser]Parser::add_single_val_to_arg: cur_idx:=4
[clap_builder::parser::arg_matcher]ArgMatcher::needs_more_vals: o=before, pending=0
[clap_builder::parser::arg_matcher]ArgMatcher::needs_more_vals: expected=0.., actual=0
[clap_builder::parser::parser]Parser::react not enough values passed in, leaving it to the validator to complain
[clap_builder::parser::parser]Parser::add_defaults
[clap_builder::parser::parser]Parser::add_defaults:iter:before:
[clap_builder::parser::parser]Parser::add_default_value: doesn't have conditional defaults
[clap_builder::parser::parser]Parser::add_default_value:iter:before: doesn't have default vals
[clap_builder::parser::parser]Parser::add_defaults:iter:after:
[clap_builder::parser::parser]Parser::add_default_value: doesn't have conditional defaults
[clap_builder::parser::parser]Parser::add_default_value:iter:after: doesn't have default vals
[clap_builder::parser::parser]Parser::add_defaults:iter:help:
[clap_builder::parser::parser]Parser::add_default_value: doesn't have conditional defaults
[clap_builder::parser::parser]Parser::add_default_value:iter:help: doesn't have default vals
[clap_builder::parser::validator]Validator::validate
[clap_builder::builder::command]Command::groups_for_arg: id="before"
[clap_builder::parser::validator]Conflicts::gather_direct_conflicts id="before", conflicts=[]
[clap_builder::parser::validator]Conflicts::gather_direct_conflicts id="CliWithTwoVarArgs", conflicts=[]
[clap_builder::parser::validator]Validator::validate_conflicts
[clap_builder::parser::validator]Validator::validate_exclusive
[clap_builder::parser::validator]Validator::validate_conflicts::iter: id="before"
[clap_builder::parser::validator]Conflicts::gather_conflicts: arg="before"
[clap_builder::parser::validator]Conflicts::gather_conflicts: conflicts=[]
[clap_builder::parser::validator]Validator::validate_required: required=ChildGraph([])
[clap_builder::parser::validator]Validator::gather_requires
[clap_builder::parser::validator]Validator::gather_requires:iter:"before"
[clap_builder::parser::validator]Validator::gather_requires:iter:"CliWithTwoVarArgs"
[clap_builder::parser::validator]Validator::gather_requires:iter:"CliWithTwoVarArgs":group
[clap_builder::parser::validator]Validator::validate_required: is_exclusive_present=false
[clap_builder::parser::arg_matcher]ArgMatcher::get_global_values: global_arg_vec=[]
test test::parse_some_stuff ... FAILED
failures:
---- test::parse_some_stuff stdout ----
thread 'test::parse_some_stuff' panicked at src/main.rs:45:9:
assertion left == right failed
left: ["--release", "--", "--expand-errors", "--rlimit=100"]
right: ["--release"]
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
failures:
test::parse_some_stuff
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass --bin repro-clap-two-varargs