clap
clap copied to clipboard
`ArgAction::Count` type error not caught at compile time
Please complete the following tasks
- [X] I have searched the discussions
- [X] I have searched the open and rejected issues
Rust Version
rustc 1.61.0 (fe5b13d68 2022-05-18)
Clap Version
v3.2.6
Minimal reproducible code
use clap::{ArgAction, Parser};
#[derive(Debug, Clone, Parser)]
pub struct CliArgs {
#[clap(short = 'v', action = ArgAction::Count)]
pub verbose: i32,
}
fn main() {
let _args = CliArgs::parse();
println!("Hello, world!");
}
Steps to reproduce the bug with the above code
- Run
cargo build
and observe that the program builds. - Run
cargo run
and observe that the program panics at runtime due to a type error.
Actual Behaviour
Type error causes a panic at runtime.
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `u8`,
right: `i32`: Argument `verbose`'s selected action Count contradicts `value_parser` (ValueParser::other(i32))'
Expected Behaviour
Type error should be caught at compile time.
Alternatively, allow upcasting the u8
into user`s preferred type automatically.
Thinking through this and the problems we normally have in moving an error to compile time, I think this is one case where we skip most of those.
The better solution is to automatically downcast to user provided type.
Currently, one cannot even downcast u8 -> usize
, see #4417 and #3912.
I think this is also an issue in the example on the args trait page. Currently it has:
#[derive(clap::Parser)]
struct Args {
#[command(flatten)]
logging: LogArgs,
}
#[derive(clap::Args)]
struct LogArgs {
#[arg(long, short = 'v', action = clap::ArgAction::Count)]
verbose: i8,
}
And I had something based on this that didn't work until I changed i8
to u8
Edit: submitted #4610 to fix just this example