ITADN

Generating bash completions panics when subcommand contains double-underscores (`__`)

#6339Openwgoodall01 创建于 2026-04-09
C-bugS-triage
W
wgoodall01commented
### Please complete the following tasks - [x] I have searched the [discussions](https://github.com/clap-rs/clap/discussions) - [x] I have searched the [open](https://github.com/clap-rs/clap/issues) and [rejected](https://github.com/clap-rs/clap/issues?q=is%3Aissue+label%3AS-wont-fix+is%3Aclosed) issues ### Rust Version rustc 1.93.0 (254b59607 2026-01-19) ### Clap Version clap 4.5.54, clap_complete 4.6.0 ### Minimal reproducible code ```rust use clap::{CommandFactory, Parser, Subcommand}; #[derive(Parser)] #[command(name = "myapp")] struct Cli { #[command(subcommand)] command: Commands, } #[derive(Subcommand)] enum Commands { #[command(subcommand)] Group(Group), } #[derive(Subcommand)] enum Group { /// A normal subcommand Normal, /// A hidden subcommand with double-underscore prefix #[command(name = "__hidden", hide = true)] Hidden, } fn main() { let mut cmd = Cli::command(); clap_complete::generate( clap_complete::Shell::Bash, &mut cmd, "myapp", &mut std::io::stdout(), ); } ``` ### Steps to reproduce the bug with the above code `cargo run` ### Actual Behaviour The program panics: ``` thread 'main' panicked at .cargo/registry/src/index.crates.io-.../clap_complete-4.6.0/src/aot/generator/utils.rs:30:39: called `Option::unwrap()` on a `None` value ``` Only the bash generator is affected. Zsh, fish, powershell, and elvish all work fine with the same command tree. ### Expected Behaviour The bash completion script should be generated successfully, the same as it is for other shells. If subcommand names containing `__` are unsupported, `generate()` should return an error rather than panicking. ### Additional Context The bash generator uses `__` as a path separator to build and resolve subcommand paths internally. In `subcommand_details()` (bash.rs:144), bin_names are joined with `__`: ```rust .map(|x| x.1.replace(' ', "__")) ``` For the command `__hidden` with bin_name `"myapp group __hidden"`, this produces `"myapp__group____hidden"` (four consecutive underscores). Later, `all_options_for_path()` (bash.rs:283) splits the path back apart: ```rust let p = utils::find_subcommand_with_path(cmd, path.split("__").skip(1).collect()); ``` Splitting `"myapp__group____hidden"` by `__` yields `["myapp", "group", "", "hidden"]`. After skip(1), the lookup path is `["group", "", "hidden"]`. The empty string `""` doesn't match any subcommand, so `find_subcommand_with_path` hits the `unwrap()` on line 30 and panics. The most robust fix would be to track subcommand paths as `Vec<String>` rather than a flat `__`-delimited string. For now, my workaround is to rename the subcommand to avoid `__` (e.g. `_hidden` with a single underscore). ### Debug Output N/A -- the panic occurs in clap_complete's code generation, not during argument parsing, so the clap `debug` feature doesn't produce relevant output.
0 条评论