From 8ad9561ece8ec5979f87c43cb377827693be96b8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 21 Apr 2021 16:51:10 -0700 Subject: [PATCH] Parse inner attrs on structs, enums, unions, variants --- src/data.rs | 16 ++++++++++++++-- src/derive.rs | 20 +++++++++++++------- src/item.rs | 14 ++++++++------ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/data.rs b/src/data.rs index 8292337850..b0258ca068 100644 --- a/src/data.rs +++ b/src/data.rs @@ -246,11 +246,12 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for Variant { fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; + let mut attrs = input.call(Attribute::parse_outer)?; let _visibility: Visibility = input.parse()?; let ident: Ident = input.parse()?; let fields = if input.peek(token::Brace) { - Fields::Named(input.parse()?) + let fields = parse_braced(input, &mut attrs)?; + Fields::Named(fields) } else if input.peek(token::Paren) { Fields::Unnamed(input.parse()?) } else { @@ -294,6 +295,17 @@ pub mod parsing { } } + pub(crate) fn parse_braced( + input: ParseStream, + attrs: &mut Vec, + ) -> Result { + let content; + let brace_token = braced!(content in input); + attr::parsing::parse_inner(&content, attrs)?; + let named = content.parse_terminated(Field::parse_named)?; + Ok(FieldsNamed { brace_token, named }) + } + impl Field { /// Parses a named (braced struct) field. #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] diff --git a/src/derive.rs b/src/derive.rs index af9bb91b7a..17387e4567 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -95,7 +95,7 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for DeriveInput { fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; + let mut attrs = input.call(Attribute::parse_outer)?; let vis = input.parse::()?; let lookahead = input.lookahead1(); @@ -103,7 +103,7 @@ pub mod parsing { let struct_token = input.parse::()?; let ident = input.parse::()?; let generics = input.parse::()?; - let (where_clause, fields, semi) = data_struct(input)?; + let (where_clause, fields, semi) = data_struct(input, &mut attrs)?; Ok(DeriveInput { attrs, vis, @@ -122,7 +122,7 @@ pub mod parsing { let enum_token = input.parse::()?; let ident = input.parse::()?; let generics = input.parse::()?; - let (where_clause, brace, variants) = data_enum(input)?; + let (where_clause, brace, variants) = data_enum(input, &mut attrs)?; Ok(DeriveInput { attrs, vis, @@ -141,7 +141,7 @@ pub mod parsing { let union_token = input.parse::()?; let ident = input.parse::()?; let generics = input.parse::()?; - let (where_clause, fields) = data_union(input)?; + let (where_clause, fields) = data_union(input, &mut attrs)?; Ok(DeriveInput { attrs, vis, @@ -163,6 +163,7 @@ pub mod parsing { pub fn data_struct( input: ParseStream, + attrs: &mut Vec, ) -> Result<(Option, Fields, Option)> { let mut lookahead = input.lookahead1(); let mut where_clause = None; @@ -187,7 +188,7 @@ pub mod parsing { Err(lookahead.error()) } } else if lookahead.peek(token::Brace) { - let fields = input.parse()?; + let fields = data::parsing::parse_braced(input, attrs)?; Ok((where_clause, Fields::Named(fields), None)) } else if lookahead.peek(Token![;]) { let semi = input.parse()?; @@ -199,6 +200,7 @@ pub mod parsing { pub fn data_enum( input: ParseStream, + attrs: &mut Vec, ) -> Result<( Option, token::Brace, @@ -208,14 +210,18 @@ pub mod parsing { let content; let brace = braced!(content in input); + attr::parsing::parse_inner(&content, attrs)?; let variants = content.parse_terminated(Variant::parse)?; Ok((where_clause, brace, variants)) } - pub fn data_union(input: ParseStream) -> Result<(Option, FieldsNamed)> { + pub fn data_union( + input: ParseStream, + attrs: &mut Vec, + ) -> Result<(Option, FieldsNamed)> { let where_clause = input.parse()?; - let fields = input.parse()?; + let fields = data::parsing::parse_braced(input, attrs)?; Ok((where_clause, fields)) } } diff --git a/src/item.rs b/src/item.rs index 291a5aced1..bf2abd6edc 100644 --- a/src/item.rs +++ b/src/item.rs @@ -2009,12 +2009,13 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ItemStruct { fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; + let mut attrs = input.call(Attribute::parse_outer)?; let vis = input.parse::()?; let struct_token = input.parse::()?; let ident = input.parse::()?; let generics = input.parse::()?; - let (where_clause, fields, semi_token) = derive::parsing::data_struct(input)?; + let (where_clause, fields, semi_token) = + derive::parsing::data_struct(input, &mut attrs)?; Ok(ItemStruct { attrs, vis, @@ -2033,12 +2034,13 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ItemEnum { fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; + let mut attrs = input.call(Attribute::parse_outer)?; let vis = input.parse::()?; let enum_token = input.parse::()?; let ident = input.parse::()?; let generics = input.parse::()?; - let (where_clause, brace_token, variants) = derive::parsing::data_enum(input)?; + let (where_clause, brace_token, variants) = + derive::parsing::data_enum(input, &mut attrs)?; Ok(ItemEnum { attrs, vis, @@ -2057,12 +2059,12 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ItemUnion { fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; + let mut attrs = input.call(Attribute::parse_outer)?; let vis = input.parse::()?; let union_token = input.parse::()?; let ident = input.parse::()?; let generics = input.parse::()?; - let (where_clause, fields) = derive::parsing::data_union(input)?; + let (where_clause, fields) = derive::parsing::data_union(input, &mut attrs)?; Ok(ItemUnion { attrs, vis,