diff --git a/CHANGELOG.md b/CHANGELOG.md index ccdde68..650afea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v0.3.21 (2020-11-30) + +* Fixed [another breakage](https://github.com/TeXitoi/structopt/issues/447) + when the struct is placed inside a `macro_rules!` macro. + # v0.3.20 (2020-10-12) * Fixed [a breakage](https://github.com/TeXitoi/structopt/issues/439) diff --git a/Cargo.toml b/Cargo.toml index 7c4efaf..fdad9ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "structopt" -version = "0.3.20" +version = "0.3.21" edition = "2018" authors = ["Guillaume Pinot ", "others"] description = "Parse command line argument by defining a struct." @@ -28,7 +28,7 @@ travis-ci = { repository = "TeXitoi/structopt" } [dependencies] clap = { version = "2.33", default-features = false } -structopt-derive = { path = "structopt-derive", version = "=0.4.13" } +structopt-derive = { path = "structopt-derive", version = "=0.4.14" } lazy_static = "1.4.0" paw_dep = { version = "1", optional = true, package = "paw" } diff --git a/structopt-derive/Cargo.toml b/structopt-derive/Cargo.toml index 176b34a..c346198 100644 --- a/structopt-derive/Cargo.toml +++ b/structopt-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "structopt-derive" -version = "0.4.13" +version = "0.4.14" edition = "2018" authors = ["Guillaume Pinot "] description = "Parse command line argument by defining a struct, derive crate." diff --git a/structopt-derive/src/lib.rs b/structopt-derive/src/lib.rs index b99bd35..b818386 100644 --- a/structopt-derive/src/lib.rs +++ b/structopt-derive/src/lib.rs @@ -647,16 +647,19 @@ fn gen_from_subcommand( _ => false, }); + let other = format_ident!("other"); + let matches = format_ident!("matches"); + let external = match ext_subcmd { Some((span, var_name, str_ty, values_of)) => quote_spanned! { span=> - match other { + match #other { ("", ::std::option::Option::None) => None, - (external, Some(matches)) => { + (external, Some(#matches)) => { ::std::option::Option::Some(#name::#var_name( ::std::iter::once(#str_ty::from(external)) .chain( - matches.#values_of("").into_iter().flatten().map(#str_ty::from) + #matches.#values_of("").into_iter().flatten().map(#str_ty::from) ) .collect::<::std::vec::Vec<_>>() )) @@ -682,7 +685,7 @@ fn gen_from_subcommand( Unit => quote!(), Unnamed(ref fields) if fields.unnamed.len() == 1 => { let ty = &fields.unnamed[0]; - quote!( ( <#ty as ::structopt::StructOpt>::from_clap(matches) ) ) + quote!( ( <#ty as ::structopt::StructOpt>::from_clap(#matches) ) ) } Unnamed(..) => abort!( variant.ident, @@ -691,7 +694,7 @@ fn gen_from_subcommand( }; quote! { - (#sub_name, Some(matches)) => { + (#sub_name, Some(#matches)) => { Some(#name :: #variant_name #constructor_block) } } @@ -704,7 +707,7 @@ fn gen_from_subcommand( let ty = &fields.unnamed[0]; quote! { if let Some(res) = - <#ty as ::structopt::StructOptInternal>::from_subcommand(other) + <#ty as ::structopt::StructOptInternal>::from_subcommand(#other) { return Some(#name :: #variant_name (res)); } @@ -723,7 +726,7 @@ fn gen_from_subcommand( ) -> Option { match sub { #( #match_arms, )* - other => { + #other => { #( #child_subcommands )else*; #external } diff --git a/tests/regressions.rs b/tests/regressions.rs index 876e7ed..3847dc2 100644 --- a/tests/regressions.rs +++ b/tests/regressions.rs @@ -23,3 +23,23 @@ fn invisible_group_issue_439() { assert!(!help.contains("--x ")); Opts::from_iter_safe(&["test", "--x"]).unwrap(); } + +#[test] +fn issue_447() { + macro_rules! Command { + ( $name:ident, [ + #[$meta:meta] $var:ident($inner:ty) + ] ) => { + #[derive(Debug, PartialEq, structopt::StructOpt)] + enum $name { + #[$meta] + $var($inner), + } + }; + } + + Command! {GitCmd, [ + #[structopt(external_subcommand)] + Ext(Vec) + ]} +} diff --git a/tests/ui/external_subcommand_wrong_type.stderr b/tests/ui/external_subcommand_wrong_type.stderr index 1966225..73f12d2 100644 --- a/tests/ui/external_subcommand_wrong_type.stderr +++ b/tests/ui/external_subcommand_wrong_type.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/external_subcommand_wrong_type.rs:13:15 | 13 | Other(Vec) - | ^^^^^^^ expected struct `std::ffi::CString`, found struct `std::ffi::OsString` + | ^^^^^^^ expected struct `CString`, found struct `OsString` | - = note: expected struct `std::vec::Vec` - found struct `std::vec::Vec` + = note: expected struct `Vec` + found struct `Vec` diff --git a/tests/ui/non_existent_attr.stderr b/tests/ui/non_existent_attr.stderr index e5edb56..61f784e 100644 --- a/tests/ui/non_existent_attr.stderr +++ b/tests/ui/non_existent_attr.stderr @@ -1,5 +1,5 @@ -error[E0599]: no method named `non_existing_attribute` found for struct `structopt::clap::Arg<'_, '_>` in the current scope +error[E0599]: no method named `non_existing_attribute` found for struct `Arg<'_, '_>` in the current scope --> $DIR/non_existent_attr.rs:14:24 | 14 | #[structopt(short, non_existing_attribute = 1)] - | ^^^^^^^^^^^^^^^^^^^^^^ method not found in `structopt::clap::Arg<'_, '_>` + | ^^^^^^^^^^^^^^^^^^^^^^ method not found in `Arg<'_, '_>` diff --git a/tests/ui/skip_without_default.stderr b/tests/ui/skip_without_default.stderr index 330898f..b5d702a 100644 --- a/tests/ui/skip_without_default.stderr +++ b/tests/ui/skip_without_default.stderr @@ -1,9 +1,7 @@ -error[E0277]: the trait bound `Kind: std::default::Default` is not satisfied +error[E0277]: the trait bound `Kind: Default` is not satisfied --> $DIR/skip_without_default.rs:22:17 | 22 | #[structopt(skip)] - | ^^^^ the trait `std::default::Default` is not implemented for `Kind` + | ^^^^ the trait `Default` is not implemented for `Kind` | = note: required by `std::default::Default::default` - -For more information about this error, try `rustc --explain E0277`.