From 4f17f998cb7c196b7e0b0eec8d859ae02c20a3ef Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Oct 2022 15:59:45 -0500 Subject: [PATCH] fix(derive): Better flatten type errors --- clap_derive/src/derives/args.rs | 26 +++++++++++++++++----- clap_derive/src/derives/subcommand.rs | 8 +++---- clap_derive/src/item.rs | 31 ++++++++++++++++----------- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/clap_derive/src/derives/args.rs b/clap_derive/src/derives/args.rs index 21786505..915e717e 100644 --- a/clap_derive/src/derives/args.rs +++ b/clap_derive/src/derives/args.rs @@ -202,7 +202,7 @@ pub fn gen_augment( #implicit_methods; }) } - Kind::Flatten => { + Kind::Flatten(_) => { let ty = &field.ty; let next_help_heading = item.next_help_heading(); let next_display_order = item.next_display_order(); @@ -350,7 +350,7 @@ pub fn gen_augment( .iter() .filter(|(_field, item)| { let kind = item.kind(); - matches!(*kind, Kind::Flatten) + matches!(*kind, Kind::Flatten(_)) }) .count(); if 0 < possible_group_members_len { @@ -429,8 +429,24 @@ pub fn gen_constructor(fields: &[(&Field, Item)]) -> TokenStream { } } - Kind::Flatten => quote_spanned! { kind.span()=> - #field_name: clap::FromArgMatches::from_arg_matches_mut(#arg_matches)? + Kind::Flatten(ty) => { + match **ty { + Ty::Other => { + quote_spanned! { kind.span()=> + #field_name: clap::FromArgMatches::from_arg_matches_mut(#arg_matches)? + } + }, + Ty::Vec | + Ty::Option | + Ty::OptionOption | + Ty::OptionVec => { + abort!( + ty.span(), + "{} types are not supported for flatten", + ty.as_str() + ); + } + } }, Kind::Skip(val, _) => match val { @@ -506,7 +522,7 @@ pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> TokenStream { } } - Kind::Flatten => quote_spanned! { kind.span()=> { + Kind::Flatten(_) => quote_spanned! { kind.span()=> { #access clap::FromArgMatches::update_from_arg_matches_mut(#field_name, #arg_matches)?; } diff --git a/clap_derive/src/derives/subcommand.rs b/clap_derive/src/derives/subcommand.rs index 1989e82f..b437e42c 100644 --- a/clap_derive/src/derives/subcommand.rs +++ b/clap_derive/src/derives/subcommand.rs @@ -173,7 +173,7 @@ fn gen_augment( Some(subcommand) } - Kind::Flatten => match variant.fields { + Kind::Flatten(_) => match variant.fields { Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { let ty = &unnamed[0]; let deprecations = if !override_required { @@ -363,7 +363,7 @@ fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> TokenStream { }) .partition(|(_, item)| { let kind = item.kind(); - matches!(&*kind, Kind::Flatten) + matches!(&*kind, Kind::Flatten(_)) }); let subcommands = variants.iter().map(|(_variant, item)| { @@ -464,7 +464,7 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { }) .partition(|(_, item)| { let kind = item.kind(); - matches!(&*kind, Kind::Flatten) + matches!(&*kind, Kind::Flatten(_)) }); let subcommands = variants.iter().map(|(variant, item)| { @@ -571,7 +571,7 @@ fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { }) .partition(|(_, item)| { let kind = item.kind(); - matches!(&*kind, Kind::Flatten) + matches!(&*kind, Kind::Flatten(_)) }); let subcommands = variants.iter().map(|(variant, item)| { diff --git a/clap_derive/src/item.rs b/clap_derive/src/item.rs index 68af9d62..b9f64da6 100644 --- a/clap_derive/src/item.rs +++ b/clap_derive/src/item.rs @@ -148,7 +148,7 @@ impl Item { } match &*res.kind { - Kind::Flatten => { + Kind::Flatten(_) => { if res.has_explicit_methods() { abort!( res.kind.span(), @@ -224,7 +224,7 @@ impl Item { } match &*res.kind { - Kind::Flatten => { + Kind::Flatten(_) => { if res.has_explicit_methods() { abort!( res.kind.span(), @@ -383,7 +383,12 @@ impl Item { let expr = attr.value_or_abort(); abort!(expr, "attribute `{}` does not accept a value", attr.name); } - let kind = Sp::new(Kind::Flatten, attr.name.clone().span()); + let ty = self + .kind() + .ty() + .cloned() + .unwrap_or_else(|| Sp::new(Ty::Other, self.kind.span())); + let kind = Sp::new(Kind::Flatten(ty), attr.name.clone().span()); Some(kind) } Some(MagicAttrName::Skip) if actual_attr_kind != AttrKind::Group => { @@ -902,10 +907,10 @@ impl Item { match (self.kind.get(), kind.get()) { (Kind::Arg(_), Kind::FromGlobal(_)) | (Kind::Arg(_), Kind::Subcommand(_)) - | (Kind::Arg(_), Kind::Flatten) + | (Kind::Arg(_), Kind::Flatten(_)) | (Kind::Arg(_), Kind::Skip(_, _)) | (Kind::Command(_), Kind::Subcommand(_)) - | (Kind::Command(_), Kind::Flatten) + | (Kind::Command(_), Kind::Flatten(_)) | (Kind::Command(_), Kind::Skip(_, _)) | (Kind::Command(_), Kind::ExternalSubcommand) | (Kind::Value, Kind::Skip(_, _)) => { @@ -1142,7 +1147,7 @@ pub enum Kind { Value, FromGlobal(Sp), Subcommand(Sp), - Flatten, + Flatten(Sp), Skip(Option, AttrKind), ExternalSubcommand, } @@ -1155,7 +1160,7 @@ impl Kind { Self::Value => "value", Self::FromGlobal(_) => "from_global", Self::Subcommand(_) => "subcommand", - Self::Flatten => "flatten", + Self::Flatten(_) => "flatten", Self::Skip(_, _) => "skip", Self::ExternalSubcommand => "external_subcommand", } @@ -1168,7 +1173,7 @@ impl Kind { Self::Value => AttrKind::Value, Self::FromGlobal(_) => AttrKind::Arg, Self::Subcommand(_) => AttrKind::Command, - Self::Flatten => AttrKind::Command, + Self::Flatten(_) => AttrKind::Command, Self::Skip(_, kind) => *kind, Self::ExternalSubcommand => AttrKind::Command, } @@ -1176,10 +1181,12 @@ impl Kind { pub fn ty(&self) -> Option<&Sp> { match self { - Self::Arg(ty) | Self::Command(ty) | Self::FromGlobal(ty) | Self::Subcommand(ty) => { - Some(ty) - } - Self::Value | Self::Flatten | Self::Skip(_, _) | Self::ExternalSubcommand => None, + Self::Arg(ty) + | Self::Command(ty) + | Self::Flatten(ty) + | Self::FromGlobal(ty) + | Self::Subcommand(ty) => Some(ty), + Self::Value | Self::Skip(_, _) | Self::ExternalSubcommand => None, } } }