Skip to content

Cannot use non-literal expressions for name attribute #5407

@mwu-tow

Description

@mwu-tow

Please complete the following tasks

Rust Version

rustc 1.76.0 (07dca489a 2024-02-04)

Clap Version

4.5.3

Minimal reproducible code

use clap::Parser;

pub trait HasName {
    const NAME: &'static str;
}

pub struct Foo;

impl HasName for Foo {
    const NAME: &'static str = "foo";
}

/// Simple program to greet a person
#[derive(Parser, Debug)]
struct Args<T: HasName> {
    /// Name of the person to greet
    #[clap(name = T::NAME, short, long)]
    name: String,

    #[clap(skip)]
    phantom: std::marker::PhantomData<T>,
}

fn main() {
    Args::<Foo>::parse();
}

Steps to reproduce the bug with the above code

cargo build

Actual Behaviour

Build error:

error: expected a literal
  --> src\main.rs:17:19
   |
17 |     #[clap(name = T::NAME, short, long)]
   |                   ^^^^^^^
   |
   = note: only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`

Expected Behaviour

This code worked in clap 3.2.25 and was not documented as a change, so I think it still should work.

Also, the documentation says that the name attribute argument is an expression, so I would expect it to work. Especially since there is no restriction on the Command::name API. I don't think there are similar restrictions on other attributes.

Additional Context

This blocks me from migrating to clap v4. I relied on this pattern to reuse the same structure definition, while avoiding the name collisions.

Debug Output

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions