Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade syn to v2 #226

Merged
merged 22 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ darling_macro = { version = "=0.14.4", path = "macro" }
[dev-dependencies]
proc-macro2 = "1.0.37"
quote = "1.0.18"
syn = "1.0.91"
syn = "2.0.0"

[target.'cfg(compiletests)'.dev-dependencies]
rustversion = "1.0.9"
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ suggestions = ["strsim"]
ident_case = "1.0.1"
proc-macro2 = "1.0.37"
quote = "1.0.18"
syn = { version = "1.0.91", features = ["full", "extra-traits"] }
syn = { version = "2.0.0", features = ["full", "extra-traits"] }
fnv = "1.0.7"
strsim = { version = "0.10.0", optional = true }
40 changes: 40 additions & 0 deletions core/src/ast/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use std::{slice, vec};

use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned, ToTokens};
use syn::ext::IdentExt;
use syn::parse::Parser;
use syn::spanned::Spanned;
use syn::Token;

use crate::usage::{
self, IdentRefSet, IdentSet, LifetimeRefSet, LifetimeSet, UsesLifetimes, UsesTypeParams,
Expand Down Expand Up @@ -410,6 +413,43 @@ impl<'a> From<&'a syn::Fields> for Style {
}
}

#[derive(Debug)]
pub enum NestedMeta {
Meta(syn::Meta),
Lit(syn::Lit),
}
TedDriggs marked this conversation as resolved.
Show resolved Hide resolved

impl NestedMeta {
pub fn parse_meta_list(tokens: TokenStream) -> syn::Result<Vec<Self>> {
syn::punctuated::Punctuated::<NestedMeta, Token![,]>::parse_terminated
.parse2(tokens)
.map(|punctuated| punctuated.into_iter().collect())
}
}

impl syn::parse::Parse for NestedMeta {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
if input.peek(syn::Lit) && !(input.peek(syn::LitBool) && input.peek2(Token![=])) {
input.parse().map(NestedMeta::Lit)
} else if input.peek(syn::Ident::peek_any)
|| input.peek(Token![::]) && input.peek3(syn::Ident::peek_any)
{
input.parse().map(NestedMeta::Meta)
} else {
Err(input.error("expected identifier or literal"))
}
}
}

impl ToTokens for NestedMeta {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
NestedMeta::Meta(meta) => meta.to_tokens(tokens),
NestedMeta::Lit(lit) => lit.to_tokens(tokens),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
14 changes: 7 additions & 7 deletions core/src/ast/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{FromGenericParam, FromGenerics, FromTypeParam, Result};
pub trait GenericParamExt {
/// The type this GenericParam uses to represent type params and their bounds
type TypeParam;
type LifetimeDef;
type LifetimeParam;
type ConstParam;

/// If this GenericParam is a type param, get the underlying value.
Expand All @@ -23,7 +23,7 @@ pub trait GenericParamExt {
}

/// If this GenericParam is a lifetime, get the underlying value.
fn as_lifetime_def(&self) -> Option<&Self::LifetimeDef> {
fn as_lifetime_def(&self) -> Option<&Self::LifetimeParam> {
TedDriggs marked this conversation as resolved.
Show resolved Hide resolved
None
}

Expand All @@ -35,7 +35,7 @@ pub trait GenericParamExt {

impl GenericParamExt for syn::GenericParam {
type TypeParam = syn::TypeParam;
type LifetimeDef = syn::LifetimeDef;
type LifetimeParam = syn::LifetimeParam;
type ConstParam = syn::ConstParam;

fn as_type_param(&self) -> Option<&Self::TypeParam> {
Expand All @@ -46,7 +46,7 @@ impl GenericParamExt for syn::GenericParam {
}
}

fn as_lifetime_def(&self) -> Option<&Self::LifetimeDef> {
fn as_lifetime_def(&self) -> Option<&Self::LifetimeParam> {
if let syn::GenericParam::Lifetime(ref val) = *self {
Some(val)
} else {
Expand All @@ -65,7 +65,7 @@ impl GenericParamExt for syn::GenericParam {

impl GenericParamExt for syn::TypeParam {
type TypeParam = syn::TypeParam;
type LifetimeDef = ();
type LifetimeParam = ();
type ConstParam = ();

fn as_type_param(&self) -> Option<&Self::TypeParam> {
Expand All @@ -75,7 +75,7 @@ impl GenericParamExt for syn::TypeParam {

/// A mirror of `syn::GenericParam` which is generic over all its contents.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum GenericParam<T = syn::TypeParam, L = syn::LifetimeDef, C = syn::ConstParam> {
pub enum GenericParam<T = syn::TypeParam, L = syn::LifetimeParam, C = syn::ConstParam> {
Type(T),
Lifetime(L),
Const(C),
Expand Down Expand Up @@ -103,7 +103,7 @@ impl<T: FromTypeParam> FromGenericParam for GenericParam<T> {

impl<T, L, C> GenericParamExt for GenericParam<T, L, C> {
type TypeParam = T;
type LifetimeDef = L;
type LifetimeParam = L;
type ConstParam = C;

fn as_type_param(&self) -> Option<&T> {
Expand Down
19 changes: 12 additions & 7 deletions core/src/codegen/attr_extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,18 @@ pub trait ExtractAttribute {
#(#attr_names)|* => {
match ::darling::util::parse_attribute_to_meta_list(__attr) {
::darling::export::Ok(__data) => {
if __data.nested.is_empty() {
continue;
match ::darling::export::NestedMeta::parse_meta_list(__data.tokens.clone()) {
::darling::export::Ok(ref __items) => {
if __items.is_empty() {
continue;
}

#core_loop
}
::darling::export::Err(__err) => {
__errors.push(__err.into());
}
}

let __items = &__data.nested;

#core_loop
}
// darling was asked to handle this attribute name, but the actual attribute
// isn't one that darling can work with. This either indicates a typing error
Expand Down Expand Up @@ -92,7 +97,7 @@ pub trait ExtractAttribute {

for __attr in #attrs_accessor {
// Filter attributes based on name
match ::darling::export::ToString::to_string(&__attr.path.clone().into_token_stream()).as_str() {
match ::darling::export::ToString::to_string(&__attr.path().clone().into_token_stream()).as_str() {
#parse_handled
#forward_unhandled
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/codegen/from_meta_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'a> ToTokens for FromMetaImpl<'a> {
let post_transform = base.post_transform_call();

quote!(
fn from_list(__items: &[::darling::export::syn::NestedMeta]) -> ::darling::Result<Self> {
fn from_list(__items: &[::darling::export::NestedMeta]) -> ::darling::Result<Self> {

#decls

Expand Down Expand Up @@ -91,13 +91,13 @@ impl<'a> ToTokens for FromMetaImpl<'a> {
};

quote!(
fn from_list(__outer: &[::darling::export::syn::NestedMeta]) -> ::darling::Result<Self> {
fn from_list(__outer: &[::darling::export::NestedMeta]) -> ::darling::Result<Self> {
// An enum must have exactly one value inside the parentheses if it's not a unit
// match arm
match __outer.len() {
0 => ::darling::export::Err(::darling::Error::too_few_items(1)),
1 => {
if let ::darling::export::syn::NestedMeta::Meta(ref __nested) = __outer[0] {
if let ::darling::export::NestedMeta::Meta(ref __nested) = __outer[0] {
match ::darling::util::path_to_string(__nested.path()).as_ref() {
#(#struct_arms)*
__other => ::darling::export::Err(::darling::Error::#unknown_variant_err.with_span(__nested))
Expand Down
3 changes: 2 additions & 1 deletion core/src/codegen/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ impl<'a> ToTokens for DataMatchArm<'a> {
tokens.append_all(quote!(
#name_in_attr => {
if let ::darling::export::syn::Meta::List(ref __data) = *__nested {
let __items = &__data.nested;
let __items = ::darling::export::NestedMeta::parse_meta_list(__data.tokens.clone())?;
let __items = &__items;

#declare_errors

Expand Down
4 changes: 2 additions & 2 deletions core/src/codegen/variant_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ impl<'a> FieldsGen<'a> {
quote!(
for __item in __items {
match *__item {
::darling::export::syn::NestedMeta::Meta(ref __inner) => {
::darling::export::NestedMeta::Meta(ref __inner) => {
let __name = ::darling::util::path_to_string(__inner.path());
match __name.as_str() {
#(#arms)*
__other => { #handle_unknown }
}
}
::darling::export::syn::NestedMeta::Lit(ref __inner) => {
::darling::export::NestedMeta::Lit(ref __inner) => {
__errors.push(::darling::Error::unsupported_format("literal")
.with_span(__inner));
}
Expand Down
52 changes: 50 additions & 2 deletions core/src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::iter::{self, Iterator};
use std::string::ToString;
use std::vec;
use syn::spanned::Spanned;
use syn::{Lit, LitStr, Path};
use syn::{Lit, LitStr, Path, Expr};

#[cfg(feature = "diagnostics")]
mod child;
Expand Down Expand Up @@ -149,6 +149,53 @@ impl Error {
Error::new(ErrorKind::UnexpectedType(ty.into()))
}

pub fn unexpected_expr_type(expr: &Expr) -> Self {
Error::unexpected_type(match *expr {
Expr::Array(_) => "array",
Expr::Assign(_) => "assign",
Expr::Async(_) => "async",
Expr::Await(_) => "await",
Expr::Binary(_) => "binary",
Expr::Block(_) => "block",
Expr::Break(_) => "break",
Expr::Call(_) => "call",
Expr::Cast(_) => "cast",
Expr::Closure(_) => "closure",
Expr::Const(_) => "const",
Expr::Continue(_) => "continue",
Expr::Field(_) => "field",
Expr::ForLoop(_) => "for_loop",
Expr::Group(_) => "group",
Expr::If(_) => "if",
Expr::Index(_) => "index",
Expr::Infer(_) => "infer",
Expr::Let(_) => "let",
Expr::Lit(_) => "lit",
Expr::Loop(_) => "loop",
Expr::Macro(_) => "macro",
Expr::Match(_) => "match",
Expr::MethodCall(_) => "method_call",
Expr::Paren(_) => "paren",
Expr::Path(_) => "path",
Expr::Range(_) => "range",
Expr::Reference(_) => "reference",
Expr::Repeat(_) => "repeat",
Expr::Return(_) => "return",
Expr::Struct(_) => "struct",
Expr::Try(_) => "try",
Expr::TryBlock(_) => "try_block",
Expr::Tuple(_) => "tuple",
Expr::Unary(_) => "unary",
Expr::Unsafe(_) => "unsafe",
Expr::Verbatim(_) => "verbatim",
Expr::While(_) => "while",
Expr::Yield(_) => "yield",
TedDriggs marked this conversation as resolved.
Show resolved Hide resolved
// non-exhaustive enum
_ => "unknown",
})
.with_span(expr)
}

/// Creates a new error for a field which has an unexpected literal type. This will automatically
/// extract the literal type name from the passed-in `Lit` and set the span to encompass only the
/// literal value.
Expand Down Expand Up @@ -188,6 +235,8 @@ impl Error {
Lit::Float(_) => "float",
Lit::Bool(_) => "bool",
Lit::Verbatim(_) => "verbatim",
// non-exhaustive enum
_ => "unknown",
})
.with_span(lit)
}
Expand Down Expand Up @@ -258,7 +307,6 @@ impl Error {
/// overridden:
///
/// * `FromMeta::from_meta`
/// * `FromMeta::from_nested_meta`
/// * `FromMeta::from_value`
pub fn with_span<T: Spanned>(mut self, node: &T) -> Self {
if !self.has_span() {
Expand Down
42 changes: 20 additions & 22 deletions core/src/from_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;

use syn::{Expr, Lit, Meta, NestedMeta};
use syn::{Expr, Lit, Meta};

use crate::{util::path_to_string, Error, Result};
use crate::ast::NestedMeta;
use crate::util::path_to_string;
use crate::{Error, Result};

/// Create an instance from an item in an attribute declaration.
///
Expand Down Expand Up @@ -47,14 +49,6 @@ use crate::{util::path_to_string, Error, Result};
/// * Allows for fallible parsing; will populate the target field with the result of the
/// parse attempt.
pub trait FromMeta: Sized {
fn from_nested_meta(item: &NestedMeta) -> Result<Self> {
(match *item {
NestedMeta::Lit(ref lit) => Self::from_value(lit),
NestedMeta::Meta(ref mi) => Self::from_meta(mi),
})
.map_err(|e| e.with_span(item))
}

/// Create an instance from a `syn::Meta` by dispatching to the format-appropriate
/// trait function. This generally should not be overridden by implementers.
///
Expand All @@ -66,14 +60,10 @@ pub trait FromMeta: Sized {
fn from_meta(item: &Meta) -> Result<Self> {
(match *item {
Meta::Path(_) => Self::from_word(),
Meta::List(ref value) => Self::from_list(
&value
.nested
.iter()
.cloned()
.collect::<Vec<syn::NestedMeta>>()[..],
),
Meta::NameValue(ref value) => Self::from_value(&value.lit),
Meta::List(ref value) => {
Self::from_list(&NestedMeta::parse_meta_list(value.tokens.clone())?[..])
}
Meta::NameValue(ref value) => Self::from_expr(&value.value),
})
.map_err(|e| e.with_span(item))
}
Expand Down Expand Up @@ -121,6 +111,14 @@ pub trait FromMeta: Sized {
.map_err(|e| e.with_span(value))
}

fn from_expr(expr: &Expr) -> Result<Self> {
match *expr {
Expr::Lit(ref lit) => Self::from_value(&lit.lit),
_ => Err(Error::unexpected_expr_type(expr)),
}
.map_err(|e| e.with_span(expr))
}

/// Create an instance from a char literal in a value position.
#[allow(unused_variables)]
fn from_char(value: char) -> Result<Self> {
Expand Down Expand Up @@ -519,7 +517,7 @@ impl KeyFromPath for syn::Ident {
macro_rules! hash_map {
($key:ty) => {
impl<V: FromMeta, S: BuildHasher + Default> FromMeta for HashMap<$key, V, S> {
fn from_list(nested: &[syn::NestedMeta]) -> Result<Self> {
fn from_list(nested: &[NestedMeta]) -> Result<Self> {
// Convert the nested meta items into a sequence of (path, value result) result tuples.
// An outer Err means no (key, value) structured could be found, while an Err in the
// second position of the tuple means that value was rejected by FromMeta.
Expand All @@ -530,14 +528,14 @@ macro_rules! hash_map {
.iter()
.map(|item| -> Result<(&syn::Path, Result<V>)> {
match *item {
syn::NestedMeta::Meta(ref inner) => {
NestedMeta::Meta(ref inner) => {
let path = inner.path();
Ok((
path,
FromMeta::from_meta(inner).map_err(|e| e.at_path(&path)),
))
}
syn::NestedMeta::Lit(_) => Err(Error::unsupported_format("literal")),
NestedMeta::Lit(_) => Err(Error::unsupported_format("expression")),
}
});

Expand Down Expand Up @@ -613,7 +611,7 @@ mod tests {
/// parse a string as a syn::Meta instance.
fn pm(tokens: TokenStream) -> ::std::result::Result<syn::Meta, String> {
let attribute: syn::Attribute = parse_quote!(#[#tokens]);
attribute.parse_meta().map_err(|_| "Unable to parse".into())
Ok(attribute.meta)
}

fn fm<T: FromMeta>(tokens: TokenStream) -> T {
Expand Down
Loading