Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flag misinterpreted as option when using macros on Rust 1.47.0 #439

Closed
Lakier15 opened this issue Oct 12, 2020 · 1 comment · Fixed by #440 or tbillington/kondo#34
Closed

Flag misinterpreted as option when using macros on Rust 1.47.0 #439

Lakier15 opened this issue Oct 12, 2020 · 1 comment · Fixed by #440 or tbillington/kondo#34
Assignees

Comments

@Lakier15
Copy link

It seems that with 1.47.0 macro'ing structopt causes misbehavior in the functionality of structopt. I found out that a flag gets erroneously parsed as an option instead.

In this example:

use structopt::StructOpt;

macro_rules! command {
    (
        $(#[derive($($t:tt),+)])?
        #[structopt(
            name = $name:literal,
            about = $about:literal,
            $( $var:ident = $val:expr, )*
        )]
        struct $command:ident {
            $(
                $(#[$m:meta])*
                $field:ident: $type:ty,
            )*
        }
    ) => (
        $(#[derive($($t),+)])?
        #[structopt(
            name = $name,
            about = $about,
            $( $var = $val, )*
        )]
        struct $command {
            $(
                $(#[$m])*
                $field: $type,
            )*
        }
    );
}

command!{
    #[derive(Debug, StructOpt)]
    #[structopt(
        name = "opts", 
        about = "Opts",
    )]
    struct Opts {
        #[structopt(long = "x", help = "xxx")]
        x: bool,
    }
}

fn main() {
    println!("{:?}", Opts::from_args());
}

when compiling with Rust 1.46.0

$ cargo +1.46.0 run -- --help
opts 0.1.0
Opts

USAGE:
    x [FLAGS]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
        --x          xxx

with Rust 1.47.0

$ cargo +1.47.0 run -- --help
opts 0.1.0
Opts

USAGE:
    x --x <x>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
        --x <x>    xxx

I believe that it might be because of rust-lang/rust#73084

@CreepySkeleton CreepySkeleton self-assigned this Oct 12, 2020
@CreepySkeleton
Copy link
Collaborator

This can be further simplified to

macro_rules! m {
    ($bool:ty) => {
        #[derive(Debug, StructOpt)]
        struct Opts {
            #[structopt(long = "x")]
            x: $bool
        }
    };
}

m!(bool);

Basically, tokens passed to a macro and assigned to a metavariable ($bool:ty) are wrapped in an invisible Syn::Type::Group. Our type checking doesn't account for that, and bool wasn't recognized as such.

CreepySkeleton added a commit that referenced this issue Oct 12, 2020
If memory serves, a patch like this was submitted to clap_derive,
but not to structopt. Oops.
@CreepySkeleton CreepySkeleton mentioned this issue Oct 12, 2020
CreepySkeleton added a commit that referenced this issue Oct 12, 2020
If memory serves, a patch like this was submitted to clap_derive,
but not to structopt. Oops.
CreepySkeleton added a commit that referenced this issue Oct 12, 2020
If memory serves, a patch like this was submitted to clap_derive,
but not to structopt. Oops.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment