aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2021-02-10 12:42:26 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-10 12:42:26 +0000
commit0527bafdf765c59465d8ca813c85edff696026d3 (patch)
tree6dc94fd6e23850663b29f797dde288a41e6eef78
parent49f22523c3eb148cf71047fb6a43cf895c1cf447 (diff)
parentd9012bc2cc6de16229ca3e546715296f338a5190 (diff)
downloadderive_arbitrary-0527bafdf765c59465d8ca813c85edff696026d3.tar.gz
Upgrade rust/crates/derive_arbitrary to 1.0.0-rc2 am: c16f810b6d am: 7849cd8689 am: 910c875070 am: d9012bc2cc
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/derive_arbitrary/+/1582217 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I2a8898577f7e794aba7c0d3b7d0230a8e1b61128
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp4
-rw-r--r--Cargo.toml6
-rw-r--r--Cargo.toml.orig12
-rw-r--r--METADATA10
-rw-r--r--src/lib.rs144
6 files changed, 66 insertions, 112 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 79657dc..36e1045 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "ab4adcf12045858148e93e70b85a93559ae6e214"
+ "sha1": "89a6e201efdbfe6bd1495e15ded0b1a67d651525"
}
}
diff --git a/Android.bp b/Android.bp
index 6054c0f..704d0f8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,6 +14,6 @@ rust_proc_macro {
// dependent_library ["feature_list"]
// proc-macro2-1.0.24 "default,proc-macro"
-// quote-1.0.7 "default,proc-macro"
-// syn-1.0.51 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
+// quote-1.0.8 "default,proc-macro"
+// syn-1.0.60 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
// unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index e9d3c51..a97a171 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,15 +13,15 @@
[package]
edition = "2018"
name = "derive_arbitrary"
-version = "0.4.7"
-authors = ["The Rust-Fuzz Project Developers", "Nick Fitzgerald <fitzgen@gmail.com>", "Manish Goregaokar <manishsmail@gmail.com>", "Andre Bogus <bogusandre@gmail.com>"]
+version = "1.0.0-rc2"
+authors = ["The Rust-Fuzz Project Developers", "Nick Fitzgerald <fitzgen@gmail.com>", "Manish Goregaokar <manishsmail@gmail.com>", "Andre Bogus <bogusandre@gmail.com>", "Corey Farwell <coreyf@rwell.org>"]
description = "Derives arbitrary traits"
documentation = "https://docs.rs/arbitrary/"
readme = "README.md"
keywords = ["arbitrary", "testing", "derive", "macro"]
categories = ["development-tools::testing"]
license = "MIT/Apache-2.0"
-repository = "https://github.com/nagisa/rust_arbitrary"
+repository = "https://github.com/rust-fuzz/arbitrary"
[lib]
proc_macro = true
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index f084540..09fc58a 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,14 +1,20 @@
[package]
name = "derive_arbitrary"
-version = "0.4.7" # Make sure it matches the version of the arbitrary crate itself.
-authors = ["The Rust-Fuzz Project Developers", "Nick Fitzgerald <fitzgen@gmail.com>", "Manish Goregaokar <manishsmail@gmail.com>", "Andre Bogus <bogusandre@gmail.com>"]
+version = "1.0.0-rc2" # Make sure it matches the version of the arbitrary crate itself.
+authors = [
+ "The Rust-Fuzz Project Developers",
+ "Nick Fitzgerald <fitzgen@gmail.com>",
+ "Manish Goregaokar <manishsmail@gmail.com>",
+ "Andre Bogus <bogusandre@gmail.com>",
+ "Corey Farwell <coreyf@rwell.org>",
+]
categories = ["development-tools::testing"]
edition = "2018"
keywords = ["arbitrary", "testing", "derive", "macro"]
readme = "README.md"
description = "Derives arbitrary traits"
license = "MIT/Apache-2.0"
-repository = "https://github.com/nagisa/rust_arbitrary"
+repository = "https://github.com/rust-fuzz/arbitrary"
documentation = "https://docs.rs/arbitrary/"
[dependencies]
diff --git a/METADATA b/METADATA
index edbe028..4ac17dd 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/derive_arbitrary/derive_arbitrary-0.4.7.crate"
+ value: "https://static.crates.io/crates/derive_arbitrary/derive_arbitrary-1.0.0-rc2.crate"
}
- version: "0.4.7"
+ version: "1.0.0-rc2"
license_type: NOTICE
last_upgrade_date {
- year: 2020
- month: 11
- day: 17
+ year: 2021
+ month: 2
+ day: 9
}
}
diff --git a/src/lib.rs b/src/lib.rs
index e16212d..983bd68 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,51 +1,83 @@
extern crate proc_macro;
-use proc_macro2::{Literal, TokenStream};
+use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::*;
+static ARBITRARY_LIFETIME_NAME: &str = "'arbitrary";
+
#[proc_macro_derive(Arbitrary)]
pub fn derive_arbitrary(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = syn::parse_macro_input!(tokens as syn::DeriveInput);
+ let (lifetime_without_bounds, lifetime_with_bounds) =
+ build_arbitrary_lifetime(input.generics.clone());
- let arbitrary_method = gen_arbitrary_method(&input);
+ let arbitrary_method = gen_arbitrary_method(&input, lifetime_without_bounds.clone());
let size_hint_method = gen_size_hint_method(&input);
- let shrink_method = gen_shrink_method(&input);
let name = input.ident;
// Add a bound `T: Arbitrary` to every type parameter T.
- let generics = add_trait_bounds(input.generics);
- let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+ let generics = add_trait_bounds(input.generics, lifetime_without_bounds.clone());
+
+ // Build ImplGeneric with a lifetime (https://github.com/dtolnay/syn/issues/90)
+ let mut generics_with_lifetime = generics.clone();
+ generics_with_lifetime
+ .params
+ .push(GenericParam::Lifetime(lifetime_with_bounds));
+ let (impl_generics, _, _) = generics_with_lifetime.split_for_impl();
+
+ // Build TypeGenerics and WhereClause without a lifetime
+ let (_, ty_generics, where_clause) = generics.split_for_impl();
+
(quote! {
- impl #impl_generics arbitrary::Arbitrary for #name #ty_generics #where_clause {
+ impl #impl_generics arbitrary::Arbitrary<#lifetime_without_bounds> for #name #ty_generics #where_clause {
#arbitrary_method
#size_hint_method
- #shrink_method
}
})
.into()
}
+// Returns: (lifetime without bounds, lifetime with bounds)
+// Example: ("'arbitrary", "'arbitrary: 'a + 'b")
+fn build_arbitrary_lifetime(generics: Generics) -> (LifetimeDef, LifetimeDef) {
+ let lifetime_without_bounds =
+ LifetimeDef::new(Lifetime::new(ARBITRARY_LIFETIME_NAME, Span::call_site()));
+ let mut lifetime_with_bounds = lifetime_without_bounds.clone();
+
+ for param in generics.params.iter() {
+ if let GenericParam::Lifetime(lifetime_def) = param {
+ lifetime_with_bounds
+ .bounds
+ .push(lifetime_def.lifetime.clone());
+ }
+ }
+
+ (lifetime_without_bounds, lifetime_with_bounds)
+}
+
// Add a bound `T: Arbitrary` to every type parameter T.
-fn add_trait_bounds(mut generics: Generics) -> Generics {
+fn add_trait_bounds(mut generics: Generics, lifetime: LifetimeDef) -> Generics {
for param in generics.params.iter_mut() {
if let GenericParam::Type(type_param) = param {
- type_param.bounds.push(parse_quote!(arbitrary::Arbitrary));
+ type_param
+ .bounds
+ .push(parse_quote!(arbitrary::Arbitrary<#lifetime>));
}
}
generics
}
-fn gen_arbitrary_method(input: &DeriveInput) -> TokenStream {
+fn gen_arbitrary_method(input: &DeriveInput, lifetime: LifetimeDef) -> TokenStream {
let ident = &input.ident;
let arbitrary_structlike = |fields| {
let arbitrary = construct(fields, |_, _| quote!(arbitrary::Arbitrary::arbitrary(u)?));
let arbitrary_take_rest = construct_take_rest(fields);
quote! {
- fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
+ fn arbitrary(u: &mut arbitrary::Unstructured<#lifetime>) -> arbitrary::Result<Self> {
Ok(#ident #arbitrary)
}
- fn arbitrary_take_rest(mut u: arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
+ fn arbitrary_take_rest(mut u: arbitrary::Unstructured<#lifetime>) -> arbitrary::Result<Self> {
Ok(#ident #arbitrary_take_rest)
}
}
@@ -70,7 +102,7 @@ fn gen_arbitrary_method(input: &DeriveInput) -> TokenStream {
});
let count = data.variants.len() as u64;
quote! {
- fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
+ fn arbitrary(u: &mut arbitrary::Unstructured<#lifetime>) -> arbitrary::Result<Self> {
// Use a multiply + shift to generate a ranged random number
// with slight bias. For details, see:
// https://lemire.me/blog/2016/06/30/fast-random-shuffling
@@ -80,7 +112,7 @@ fn gen_arbitrary_method(input: &DeriveInput) -> TokenStream {
})
}
- fn arbitrary_take_rest(mut u: arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
+ fn arbitrary_take_rest(mut u: arbitrary::Unstructured<#lifetime>) -> arbitrary::Result<Self> {
// Use a multiply + shift to generate a ranged random number
// with slight bias. For details, see:
// https://lemire.me/blog/2016/06/30/fast-random-shuffling
@@ -162,87 +194,3 @@ fn gen_size_hint_method(input: &DeriveInput) -> TokenStream {
}
}
}
-
-fn gen_shrink_method(input: &DeriveInput) -> TokenStream {
- let ident = &input.ident;
- let shrink_structlike = |fields| {
- let inner = shrink(&quote!(#ident), fields, |i, field| match &field.ident {
- Some(i) => quote!(&self.#i),
- None => {
- let i = Literal::usize_unsuffixed(i);
- quote!(&self.#i)
- }
- });
- quote! {
- fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
- #inner
- }
- }
- };
-
- return match &input.data {
- Data::Struct(data) => shrink_structlike(&data.fields),
- Data::Union(data) => shrink_structlike(&Fields::Named(data.fields.clone())),
- Data::Enum(data) => {
- let variants = data.variants.iter().map(|variant| {
- let mut binding_names = Vec::new();
- let bindings = match &variant.fields {
- Fields::Named(_) => {
- let names = variant.fields.iter().map(|f| {
- let name = f.ident.as_ref().unwrap();
- binding_names.push(quote!(#name));
- name
- });
- quote!({#(#names),*})
- }
- Fields::Unnamed(_) => {
- let names = (0..variant.fields.len()).map(|i| {
- let name = quote::format_ident!("f{}", i);
- binding_names.push(quote!(#name));
- name
- });
- quote!((#(#names),*))
- }
- Fields::Unit => quote!(),
- };
- let variant_name = &variant.ident;
- let shrink = shrink(&quote!(#ident::#variant_name), &variant.fields, |i, _| {
- binding_names[i].clone()
- });
- quote!(#ident::#variant_name #bindings => { #shrink })
- });
- quote! {
- fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
- match self {
- #(#variants)*
- }
- }
- }
- }
- };
-
- fn shrink(
- prefix: &TokenStream,
- fields: &Fields,
- access_field: impl Fn(usize, &Field) -> TokenStream,
- ) -> TokenStream {
- if fields.len() == 0 {
- return quote!(Box::new(None.into_iter()));
- }
- let iters = fields.iter().enumerate().map(|(i, f)| {
- let name = quote::format_ident!("field{}", i);
- let field = access_field(i, f);
- quote! { let mut #name = arbitrary::Arbitrary::shrink(#field); }
- });
- let ctor = construct(fields, |i, _| {
- let iter = quote::format_ident!("field{}", i);
- quote!(#iter.next()?)
- });
- quote! {
- #(#iters)*
- Box::new(std::iter::from_fn(move || {
- Some(#prefix #ctor)
- }))
- }
- }
-}