Generating bash completions panics when subcommand contains double-underscores (`__`)
C-bugS-triage
### 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 条评论