summaryrefslogtreecommitdiffstats
path: root/vendor/zerovec-derive/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/zerovec-derive/src')
-rw-r--r--vendor/zerovec-derive/src/lib.rs7
-rw-r--r--vendor/zerovec-derive/src/make_ule.rs25
-rw-r--r--vendor/zerovec-derive/src/make_varule.rs78
-rw-r--r--vendor/zerovec-derive/src/utils.rs55
4 files changed, 96 insertions, 69 deletions
diff --git a/vendor/zerovec-derive/src/lib.rs b/vendor/zerovec-derive/src/lib.rs
index 5a0de6429..9c3007147 100644
--- a/vendor/zerovec-derive/src/lib.rs
+++ b/vendor/zerovec-derive/src/lib.rs
@@ -5,8 +5,7 @@
//! Proc macros for generating `ULE`, `VarULE` impls and types for the `zerovec` crate
use proc_macro::TokenStream;
-use syn::{parse_macro_input, AttributeArgs, DeriveInput};
-
+use syn::{parse_macro_input, DeriveInput, Ident};
mod make_ule;
mod make_varule;
pub(crate) mod ule;
@@ -31,7 +30,7 @@ pub fn varule_derive(input: TokenStream) -> TokenStream {
#[proc_macro_attribute]
pub fn make_ule(attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
- let attr = parse_macro_input!(attr as AttributeArgs);
+ let attr = parse_macro_input!(attr as Ident);
TokenStream::from(make_ule::make_ule_impl(attr, input))
}
@@ -39,6 +38,6 @@ pub fn make_ule(attr: TokenStream, item: TokenStream) -> TokenStream {
#[proc_macro_attribute]
pub fn make_varule(attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
- let attr = parse_macro_input!(attr as AttributeArgs);
+ let attr = parse_macro_input!(attr as Ident);
TokenStream::from(make_varule::make_varule_impl(attr, input))
}
diff --git a/vendor/zerovec-derive/src/make_ule.rs b/vendor/zerovec-derive/src/make_ule.rs
index fb94cbc2c..92a200e0b 100644
--- a/vendor/zerovec-derive/src/make_ule.rs
+++ b/vendor/zerovec-derive/src/make_ule.rs
@@ -6,15 +6,11 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use crate::utils::{self, FieldInfo, ZeroVecAttrs};
-use syn::spanned::Spanned;
-use syn::{
- parse_quote, AttributeArgs, Data, DataEnum, DataStruct, DeriveInput, Error, Expr, Fields,
- Ident, Lit,
-};
-
use std::collections::HashSet;
+use syn::spanned::Spanned;
+use syn::{parse_quote, Data, DataEnum, DataStruct, DeriveInput, Error, Expr, Fields, Ident, Lit};
-pub fn make_ule_impl(attr: AttributeArgs, mut input: DeriveInput) -> TokenStream2 {
+pub fn make_ule_impl(ule_name: Ident, mut input: DeriveInput) -> TokenStream2 {
if input.generics.type_params().next().is_some()
|| input.generics.lifetimes().next().is_some()
|| input.generics.const_params().next().is_some()
@@ -25,17 +21,6 @@ pub fn make_ule_impl(attr: AttributeArgs, mut input: DeriveInput) -> TokenStream
)
.to_compile_error();
}
-
- if attr.len() != 1 {
- return Error::new(
- input.span(),
- "#[make_ule] takes one argument for the name of the ULE type it produces",
- )
- .to_compile_error();
- }
- let arg = &attr[0];
- let ule_name: Ident = parse_quote!(#arg);
-
let sp = input.span();
let attrs = match utils::extract_attributes_common(&mut input.attrs, sp, false) {
Ok(val) => val,
@@ -112,7 +97,7 @@ fn make_ule_enum_impl(
let mut not_found = HashSet::new();
for (i, variant) in enu.variants.iter().enumerate() {
- if variant.fields != Fields::Unit {
+ if !matches!(variant.fields, Fields::Unit) {
// This can be supported in the future, see zerovec/design_doc.md
return Error::new(
variant.span(),
@@ -225,7 +210,7 @@ fn make_ule_enum_impl(
impl #name {
/// Attempt to construct the value from its corresponding integer,
- /// returning None if not possible
+ /// returning `None` if not possible
pub(crate) fn new_from_u8(value: u8) -> Option<Self> {
if value <= #max {
unsafe {
diff --git a/vendor/zerovec-derive/src/make_varule.rs b/vendor/zerovec-derive/src/make_varule.rs
index 62cf0d9db..56aa0b4f3 100644
--- a/vendor/zerovec-derive/src/make_varule.rs
+++ b/vendor/zerovec-derive/src/make_varule.rs
@@ -8,11 +8,11 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, ToTokens};
use syn::spanned::Spanned;
use syn::{
- parse_quote, AttributeArgs, Data, DeriveInput, Error, Field, Fields, GenericArgument, Ident,
- Lifetime, PathArguments, Type,
+ parse_quote, Data, DeriveInput, Error, Field, Fields, GenericArgument, Ident, Lifetime,
+ PathArguments, Type, TypePath,
};
-pub fn make_varule_impl(attr: AttributeArgs, mut input: DeriveInput) -> TokenStream2 {
+pub fn make_varule_impl(ule_name: Ident, mut input: DeriveInput) -> TokenStream2 {
if input.generics.type_params().next().is_some()
|| input.generics.const_params().next().is_some()
|| input.generics.lifetimes().count() > 1
@@ -44,20 +44,11 @@ pub fn make_varule_impl(attr: AttributeArgs, mut input: DeriveInput) -> TokenStr
let lt = lt.map(|l| &l.lifetime);
- if attr.len() != 1 {
- return Error::new(
- input.span(),
- "#[make_ule] takes one argument for the name of the ULE type it produces",
- )
- .to_compile_error();
- }
- let arg = &attr[0];
- let ule_name: Ident = parse_quote!(#arg);
-
let name = &input.ident;
+ let input_span = input.span();
let fields = match input.data {
- Data::Struct(ref s) => &s.fields,
+ Data::Struct(ref mut s) => &mut s.fields,
_ => {
return Error::new(input.span(), "#[make_varule] must be applied to a struct")
.to_compile_error();
@@ -75,16 +66,32 @@ pub fn make_varule_impl(attr: AttributeArgs, mut input: DeriveInput) -> TokenStr
let mut sized_fields = vec![];
let mut unsized_fields = vec![];
+ let mut custom_varule_idents = vec![];
+
+ for field in fields.iter_mut() {
+ match utils::extract_field_attributes(&mut field.attrs) {
+ Ok(i) => custom_varule_idents.push(i),
+ Err(e) => return e.to_compile_error(),
+ }
+ }
+
for (i, field) in fields.iter().enumerate() {
- match UnsizedField::new(field, i) {
+ match UnsizedField::new(field, i, custom_varule_idents[i].clone()) {
Ok(o) => unsized_fields.push(o),
Err(_) => sized_fields.push(FieldInfo::new_for_field(field, i)),
}
}
if unsized_fields.is_empty() {
+ let last_field_index = fields.len() - 1;
let last_field = fields.iter().next_back().unwrap();
- let e = UnsizedField::new(last_field, fields.len() - 1).unwrap_err();
+
+ let e = UnsizedField::new(
+ last_field,
+ last_field_index,
+ custom_varule_idents[last_field_index].clone(),
+ )
+ .unwrap_err();
return Error::new(last_field.span(), e).to_compile_error();
}
@@ -112,10 +119,13 @@ pub fn make_varule_impl(attr: AttributeArgs, mut input: DeriveInput) -> TokenStr
let field_inits = utils::wrap_field_inits(&field_inits, fields);
let vis = &input.vis;
- let doc = format!("[`VarULE`](zerovec::ule::VarULE) type for {name}");
+ let doc = format!(
+ "[`VarULE`](zerovec::ule::VarULE) type for [`{name}`]. See [`{name}`] for documentation."
+ );
let varule_struct: DeriveInput = parse_quote!(
#[repr(#repr_attr)]
#[doc = #doc]
+ #[allow(missing_docs)]
#vis struct #ule_name #field_inits #semi
);
@@ -138,7 +148,7 @@ pub fn make_varule_impl(attr: AttributeArgs, mut input: DeriveInput) -> TokenStr
name,
&ule_name,
lt,
- input.span(),
+ input_span,
);
let eq_impl = quote!(
@@ -409,11 +419,13 @@ enum OwnULETy<'a> {
}
/// Represents the type of the last field of the struct
-#[derive(Copy, Clone, Debug)]
+#[derive(Clone, Debug)]
enum UnsizedFieldKind<'a> {
Cow(OwnULETy<'a>),
ZeroVec(&'a Type),
VarZeroVec(&'a Type),
+ /// Custom VarULE type, and the identifier corresponding to the VarULE type
+ Custom(&'a TypePath, Ident),
// Generally you should be using the above ones for maximum zero-copy, but these will still work
Growable(OwnULETy<'a>),
@@ -568,9 +580,13 @@ impl<'a> UnsizedFields<'a> {
}
impl<'a> UnsizedField<'a> {
- fn new(field: &'a Field, index: usize) -> Result<Self, String> {
+ fn new(
+ field: &'a Field,
+ index: usize,
+ custom_varule_ident: Option<Ident>,
+ ) -> Result<Self, String> {
Ok(UnsizedField {
- kind: UnsizedFieldKind::new(&field.ty)?,
+ kind: UnsizedFieldKind::new(&field.ty, custom_varule_ident)?,
field: FieldInfo::new_for_field(field, index),
})
}
@@ -596,7 +612,10 @@ impl<'a> UnsizedField<'a> {
impl<'a> UnsizedFieldKind<'a> {
/// Construct a UnsizedFieldKind for the type of a UnsizedFieldKind if possible
- fn new(ty: &'a Type) -> Result<UnsizedFieldKind<'a>, String> {
+ fn new(
+ ty: &'a Type,
+ custom_varule_ident: Option<Ident>,
+ ) -> Result<UnsizedFieldKind<'a>, String> {
static PATH_TYPE_IDENTITY_ERROR: &str =
"Can only automatically detect corresponding VarULE types for path types \
that are Cow, ZeroVec, VarZeroVec, Box, String, or Vec";
@@ -607,6 +626,9 @@ impl<'a> UnsizedFieldKind<'a> {
match *ty {
Type::Reference(ref tyref) => OwnULETy::new(&tyref.elem, "reference").map(UnsizedFieldKind::Ref),
Type::Path(ref typath) => {
+ if let Some(custom_varule_ident) = custom_varule_ident {
+ return Ok(UnsizedFieldKind::Custom(typath, custom_varule_ident));
+ }
if typath.path.segments.len() != 1 {
return Err("Can only automatically detect corresponding VarULE types for \
path types with a single path segment".into());
@@ -678,6 +700,7 @@ impl<'a> UnsizedFieldKind<'a> {
let inner_ule = inner.varule_ty();
quote!(#inner_ule)
}
+ Self::Custom(_, ref name) => quote!(#name),
Self::ZeroVec(ref inner) => quote!(zerovec::ZeroSlice<#inner>),
Self::VarZeroVec(ref inner) => quote!(zerovec::VarZeroSlice<#inner>),
}
@@ -688,8 +711,8 @@ impl<'a> UnsizedFieldKind<'a> {
match *self {
Self::Ref(_) | Self::Cow(_) | Self::Growable(_) | Self::Boxed(_) => quote!(&*#value),
- Self::ZeroVec(_) => quote!(&*#value),
- Self::VarZeroVec(_) => quote!(&*#value),
+ Self::Custom(..) => quote!(&#value),
+ Self::ZeroVec(_) | Self::VarZeroVec(_) => quote!(&*#value),
}
}
@@ -701,15 +724,16 @@ impl<'a> UnsizedFieldKind<'a> {
| Self::Growable(ref inner)
| Self::Boxed(ref inner) => inner.varule_ty(),
- Self::ZeroVec(ty) => quote!(zerovec::ZeroSlice<#ty>),
- Self::VarZeroVec(ty) => quote!(zerovec::VarZeroSlice<#ty>),
+ Self::Custom(ref path, _) => quote!(#path),
+ Self::ZeroVec(ref ty) => quote!(zerovec::ZeroSlice<#ty>),
+ Self::VarZeroVec(ref ty) => quote!(zerovec::VarZeroSlice<#ty>),
}
}
fn has_zf(&self) -> bool {
matches!(
*self,
- Self::Ref(_) | Self::Cow(_) | Self::ZeroVec(_) | Self::VarZeroVec(_)
+ Self::Ref(_) | Self::Cow(_) | Self::ZeroVec(_) | Self::VarZeroVec(_) | Self::Custom(..)
)
}
}
diff --git a/vendor/zerovec-derive/src/utils.rs b/vendor/zerovec-derive/src/utils.rs
index 3ebf33bf0..6d37444ca 100644
--- a/vendor/zerovec-derive/src/utils.rs
+++ b/vendor/zerovec-derive/src/utils.rs
@@ -9,19 +9,16 @@ use proc_macro2::TokenStream as TokenStream2;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
-use syn::{parenthesized, parse2, Attribute, Error, Field, Fields, Ident, Index, Result, Token};
+use syn::{Attribute, Error, Field, Fields, Ident, Index, Result, Token};
// Check that there are repr attributes satisfying the given predicate
pub fn has_valid_repr(attrs: &[Attribute], predicate: impl Fn(&Ident) -> bool + Copy) -> bool {
- attrs
- .iter()
- .filter(|a| a.path.get_ident().map(|a| a == "repr").unwrap_or(false))
- .any(|a| {
- parse2::<IdentListAttribute>(a.tokens.clone())
- .ok()
- .and_then(|s| s.idents.iter().find(|s| predicate(s)).map(|_| ()))
- .is_some()
- })
+ attrs.iter().filter(|a| a.path().is_ident("repr")).any(|a| {
+ a.parse_args::<IdentListAttribute>()
+ .ok()
+ .and_then(|s| s.idents.iter().find(|s| predicate(s)).map(|_| ()))
+ .is_some()
+ })
}
// An attribute that is a list of idents
@@ -31,10 +28,8 @@ struct IdentListAttribute {
impl Parse for IdentListAttribute {
fn parse(input: ParseStream) -> Result<Self> {
- let content;
- let _paren = parenthesized!(content in input);
Ok(IdentListAttribute {
- idents: content.parse_terminated(Ident::parse)?,
+ idents: input.parse_terminated(Ident::parse, Token![,])?,
})
}
}
@@ -164,16 +159,16 @@ pub fn extract_parenthetical_zerovec_attrs(
let mut error = None;
attrs.retain(|a| {
// skip the "zerovec" part
- let second_segment = a.path.segments.iter().nth(1);
+ let second_segment = a.path().segments.iter().nth(1);
if let Some(second) = second_segment {
if second.ident == name {
- let list = match parse2::<IdentListAttribute>(a.tokens.clone()) {
+ let list = match a.parse_args::<IdentListAttribute>() {
Ok(l) => l,
Err(_) => {
error = Some(Error::new(
a.span(),
- "#[zerovec::name(..)] takes in a comma separated list of identifiers",
+ format!("#[zerovec::{name}(..)] takes in a comma separated list of identifiers"),
));
return false;
}
@@ -196,7 +191,7 @@ pub fn extract_parenthetical_zerovec_attrs(
pub fn extract_zerovec_attributes(attrs: &mut Vec<Attribute>) -> Vec<Attribute> {
let mut ret = vec![];
attrs.retain(|a| {
- if a.path.segments.len() == 2 && a.path.segments[0].ident == "zerovec" {
+ if a.path().segments.len() == 2 && a.path().segments[0].ident == "zerovec" {
ret.push(a.clone());
return false;
}
@@ -205,6 +200,30 @@ pub fn extract_zerovec_attributes(attrs: &mut Vec<Attribute>) -> Vec<Attribute>
ret
}
+/// Extract attributes from field, and return them
+///
+/// Only current field attribute is `zerovec::varule(VarUleType)`
+pub fn extract_field_attributes(attrs: &mut Vec<Attribute>) -> Result<Option<Ident>> {
+ let mut zerovec_attrs = extract_zerovec_attributes(attrs);
+ let varule = extract_parenthetical_zerovec_attrs(&mut zerovec_attrs, "varule")?;
+
+ if varule.len() > 1 {
+ return Err(Error::new(
+ varule[1].span(),
+ "Found multiple #[zerovec::varule()] on one field",
+ ));
+ }
+
+ if !zerovec_attrs.is_empty() {
+ return Err(Error::new(
+ zerovec_attrs[1].span(),
+ "Found unusable #[zerovec::] attrs on field, only #[zerovec::varule()] supported",
+ ));
+ }
+
+ Ok(varule.get(0).cloned())
+}
+
#[derive(Default, Copy, Clone)]
pub struct ZeroVecAttrs {
pub skip_kv: bool,
@@ -215,7 +234,7 @@ pub struct ZeroVecAttrs {
pub hash: bool,
}
-/// Removes all known zerovec:: attributes from attrs and validates them
+/// Removes all known zerovec:: attributes from struct attrs and validates them
pub fn extract_attributes_common(
attrs: &mut Vec<Attribute>,
span: Span,