Handling of command line arguments with 1.38.0

Before 1.38.0, I could run my program with

cargo run --bin myprog --features "feature" configs/config.json

but with 1.38.0 I get an error about not having a feature configs. By playing monkey at the keyboard, I figured out that I need

cargo run --bin myprog --features "feature" -- configs/config.json

Was I accidentally getting away with something, or was there an intentional change for 1.38.0? I saw that --features now takes more than one feature at a time, but I thought that would be

features "feature1,feature2"

Apparently not. I also see that the quotes around the feature aren't needed.

1 Like

-- (double-dash) is pretty common to signify the end of the command options.

As far as I can tell, this regression occurred due to some... odd design choices of clap regarding how .takes_value() and .multiple() interact, and should be fixed on the latest (or upcoming) nightly.


# this always worked
cargo run --features a,b

# support for this was added
cargo run --features a --features b

# support for this was also (unintentionally) added,
# hence the regression
cargo run --features a b

# This is also apparently the same.
# Why does --features have both space and commas as delimiters?
# I dunno. Blame clap.
cargo run --features "a b"

The presence or absence of quotes is irrelevant unless your feature name contains shell metacharacters. On UNIX, they are interpreted by the shell and never even seen by the program. On Windows where the raw command line string is provided to binaries, the Rust standard library parses the command line string into arguments when you use std::env::{args, args_os}, again handling the quotes before they are seen by something like cargo.

2 Likes

I've had to use -- for quite a while so there are other ways to run into this, it's been long enough that I've forgotten the original cause. I would suggest just always using -- since that should always work.

The explanation seems simple to me. cargo run forwards all positional arguments to the program. If you leave out the --, then it will only work so long as the arguments taken by your program do not begin with hyphens. (or that's how it used to be, before the --features bug)