| diff --git a/Cargo.toml b/Cargo.toml |
| index fc076e8..7ae30c8 100644 |
| --- a/Cargo.toml |
| +++ b/Cargo.toml |
| @@ -1,19 +1,6 @@ |
| -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO |
| -# |
| -# When uploading crates to the registry Cargo will automatically |
| -# "normalize" Cargo.toml files for maximal compatibility |
| -# with all versions of Cargo and also rewrite `path` dependencies |
| -# to registry (e.g., crates.io) dependencies. |
| -# |
| -# If you are reading this file be aware that the original Cargo.toml |
| -# will likely look very different (and much more reasonable). |
| -# See Cargo.toml.orig for the original contents. |
| - |
| [package] |
| -edition = "2021" |
| -rust-version = "1.63.0" |
| name = "derive_arbitrary" |
| -version = "1.3.0" |
| +version = "1.3.0" # Make sure it matches the version of the arbitrary crate itself (not including the patch version) |
| authors = [ |
| "The Rust-Fuzz Project Developers", |
| "Nick Fitzgerald <[email protected]>", |
| @@ -21,32 +8,20 @@ authors = [ |
| "Andre Bogus <[email protected]>", |
| "Corey Farwell <[email protected]>", |
| ] |
| -description = "Derives arbitrary traits" |
| -documentation = "https://docs.rs/arbitrary/" |
| -readme = "README.md" |
| -keywords = [ |
| - "arbitrary", |
| - "testing", |
| - "derive", |
| - "macro", |
| -] |
| categories = ["development-tools::testing"] |
| +edition = "2021" |
| +keywords = ["arbitrary", "testing", "derive", "macro"] |
| +readme = "README.md" |
| +description = "Derives arbitrary traits" |
| license = "MIT/Apache-2.0" |
| repository = "https://github.com/rust-fuzz/arbitrary" |
| -resolver = "1" |
| +documentation = "https://docs.rs/arbitrary/" |
| +rust-version = "1.63.0" |
| + |
| +[dependencies] |
| +proc-macro2 = "1.0" |
| +quote = "1.0" |
| +syn = { version = "2", features = ['derive', 'parsing'] } |
| |
| [lib] |
| proc_macro = true |
| - |
| -[dependencies.proc-macro2] |
| -version = "1.0" |
| - |
| -[dependencies.quote] |
| -version = "1.0" |
| - |
| -[dependencies.syn] |
| -version = "1.0.56" |
| -features = [ |
| - "derive", |
| - "parsing", |
| -] |
| diff --git a/src/container_attributes.rs b/src/container_attributes.rs |
| index 9a91ac8..269131c 100644 |
| --- a/src/container_attributes.rs |
| +++ b/src/container_attributes.rs |
| @@ -1,7 +1,7 @@ |
| use crate::ARBITRARY_ATTRIBUTE_NAME; |
| use syn::{ |
| - parse::Error, punctuated::Punctuated, DeriveInput, Lit, Meta, MetaNameValue, NestedMeta, Token, |
| - TypeParam, |
| + parse::Error, punctuated::Punctuated, DeriveInput, Expr, ExprLit, Lit, Meta, MetaNameValue, |
| + Token, TypeParam, |
| }; |
| |
| pub struct ContainerAttributes { |
| @@ -26,12 +26,12 @@ impl ContainerAttributes { |
| let mut bounds = None; |
| |
| for attr in &derive_input.attrs { |
| - if !attr.path.is_ident(ARBITRARY_ATTRIBUTE_NAME) { |
| + if !attr.path().is_ident(ARBITRARY_ATTRIBUTE_NAME) { |
| continue; |
| } |
| |
| - let meta_list = match attr.parse_meta()? { |
| - Meta::List(l) => l, |
| + let meta_list = match attr.meta { |
| + Meta::List(ref l) => l, |
| _ => { |
| return Err(Error::new_spanned( |
| attr, |
| @@ -43,13 +43,19 @@ impl ContainerAttributes { |
| } |
| }; |
| |
| - for nested_meta in meta_list.nested.iter() { |
| + for nested_meta in |
| + meta_list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)? |
| + { |
| match nested_meta { |
| - NestedMeta::Meta(Meta::NameValue(MetaNameValue { |
| + Meta::NameValue(MetaNameValue { |
| path, |
| - lit: Lit::Str(bound_str_lit), |
| + value: |
| + Expr::Lit(ExprLit { |
| + lit: Lit::Str(bound_str_lit), |
| + .. |
| + }), |
| .. |
| - })) if path.is_ident("bound") => { |
| + }) if path.is_ident("bound") => { |
| bounds |
| .get_or_insert_with(Vec::new) |
| .push(bound_str_lit.parse_with(Punctuated::parse_terminated)?); |
| diff --git a/src/field_attributes.rs b/src/field_attributes.rs |
| index 2ca0f1c..9e5922e 100644 |
| --- a/src/field_attributes.rs |
| +++ b/src/field_attributes.rs |
| @@ -1,5 +1,5 @@ |
| use crate::ARBITRARY_ATTRIBUTE_NAME; |
| -use proc_macro2::{Group, Span, TokenStream, TokenTree}; |
| +use proc_macro2::{Span, TokenStream, TokenTree}; |
| use quote::quote; |
| use syn::{spanned::Spanned, *}; |
| |
| @@ -33,7 +33,7 @@ fn fetch_attr_from_field(field: &Field) -> Result<Option<&Attribute>> { |
| .attrs |
| .iter() |
| .filter(|a| { |
| - let path = &a.path; |
| + let path = a.path(); |
| let name = quote!(#path).to_string(); |
| name == ARBITRARY_ATTRIBUTE_NAME |
| }) |
| @@ -49,38 +49,28 @@ fn fetch_attr_from_field(field: &Field) -> Result<Option<&Attribute>> { |
| } |
| |
| fn parse_attribute(attr: &Attribute) -> Result<FieldConstructor> { |
| - let group = { |
| - let mut tokens_iter = attr.clone().tokens.into_iter(); |
| - let token = tokens_iter.next().ok_or_else(|| { |
| - let msg = format!("#[{ARBITRARY_ATTRIBUTE_NAME}] cannot be empty."); |
| - syn::Error::new(attr.span(), msg) |
| - })?; |
| - match token { |
| - TokenTree::Group(g) => g, |
| - t => { |
| - let msg = format!("#[{ARBITRARY_ATTRIBUTE_NAME}] must contain a group, got: {t})"); |
| - return Err(syn::Error::new(attr.span(), msg)); |
| - } |
| - } |
| - }; |
| - parse_attribute_internals(group) |
| + if let Meta::List(ref meta_list) = attr.meta { |
| + parse_attribute_internals(meta_list) |
| + } else { |
| + let msg = format!("#[{ARBITRARY_ATTRIBUTE_NAME}] must contain a group"); |
| + Err(syn::Error::new(attr.span(), msg)) |
| + } |
| } |
| |
| -fn parse_attribute_internals(group: Group) -> Result<FieldConstructor> { |
| - let stream = group.stream(); |
| - let mut tokens_iter = stream.into_iter(); |
| +fn parse_attribute_internals(meta_list: &MetaList) -> Result<FieldConstructor> { |
| + let mut tokens_iter = meta_list.tokens.clone().into_iter(); |
| let token = tokens_iter.next().ok_or_else(|| { |
| let msg = format!("#[{ARBITRARY_ATTRIBUTE_NAME}] cannot be empty."); |
| - syn::Error::new(group.span(), msg) |
| + syn::Error::new(meta_list.span(), msg) |
| })?; |
| match token.to_string().as_ref() { |
| "default" => Ok(FieldConstructor::Default), |
| "with" => { |
| - let func_path = parse_assigned_value("with", tokens_iter, group.span())?; |
| + let func_path = parse_assigned_value("with", tokens_iter, meta_list.span())?; |
| Ok(FieldConstructor::With(func_path)) |
| } |
| "value" => { |
| - let value = parse_assigned_value("value", tokens_iter, group.span())?; |
| + let value = parse_assigned_value("value", tokens_iter, meta_list.span())?; |
| Ok(FieldConstructor::Value(value)) |
| } |
| _ => { |
| diff --git a/src/lib.rs b/src/lib.rs |
| index 5e05522..886bb49 100644 |
| --- a/src/lib.rs |
| +++ b/src/lib.rs |
| @@ -71,9 +71,9 @@ fn expand_derive_arbitrary(input: syn::DeriveInput) -> Result<TokenStream> { |
| |
| // Returns: (lifetime without bounds, lifetime with bounds) |
| // Example: ("'arbitrary", "'arbitrary: 'a + 'b") |
| -fn build_arbitrary_lifetime(generics: Generics) -> (LifetimeDef, LifetimeDef) { |
| +fn build_arbitrary_lifetime(generics: Generics) -> (LifetimeParam, LifetimeParam) { |
| let lifetime_without_bounds = |
| - LifetimeDef::new(Lifetime::new(ARBITRARY_LIFETIME_NAME, Span::call_site())); |
| + LifetimeParam::new(Lifetime::new(ARBITRARY_LIFETIME_NAME, Span::call_site())); |
| let mut lifetime_with_bounds = lifetime_without_bounds.clone(); |
| |
| for param in generics.params.iter() { |
| @@ -89,7 +89,7 @@ fn build_arbitrary_lifetime(generics: Generics) -> (LifetimeDef, LifetimeDef) { |
| |
| fn apply_trait_bounds( |
| mut generics: Generics, |
| - lifetime: LifetimeDef, |
| + lifetime: LifetimeParam, |
| container_attrs: &ContainerAttributes, |
| ) -> Result<Generics> { |
| // If user-supplied bounds exist, apply them to their matching type parameters. |
| @@ -133,7 +133,7 @@ fn apply_trait_bounds( |
| } |
| |
| // Add a bound `T: Arbitrary` to every type parameter T. |
| -fn add_trait_bounds(mut generics: Generics, lifetime: LifetimeDef) -> Generics { |
| +fn add_trait_bounds(mut generics: Generics, lifetime: LifetimeParam) -> Generics { |
| for param in generics.params.iter_mut() { |
| if let GenericParam::Type(type_param) = param { |
| type_param |
| @@ -174,13 +174,13 @@ fn with_recursive_count_guard( |
| |
| fn gen_arbitrary_method( |
| input: &DeriveInput, |
| - lifetime: LifetimeDef, |
| + lifetime: LifetimeParam, |
| recursive_count: &syn::Ident, |
| ) -> Result<TokenStream> { |
| fn arbitrary_structlike( |
| fields: &Fields, |
| ident: &syn::Ident, |
| - lifetime: LifetimeDef, |
| + lifetime: LifetimeParam, |
| recursive_count: &syn::Ident, |
| ) -> Result<TokenStream> { |
| let arbitrary = construct(fields, |_idx, field| gen_constructor_for_field(field))?; |