update to syn 2.0

This commit is contained in:
Niko Matsakis 2024-05-20 06:26:13 -04:00
parent 06b70975e9
commit 2800076857
8 changed files with 61 additions and 42 deletions

View file

@ -10,5 +10,5 @@ proc-macro = true
heck = "0.4"
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "1.0", features = ["full", "extra-traits", "visit-mut"] }
eyre = "0.6.5"
syn = { version = "2.0.64", features = ["visit-mut"] }

View file

@ -5,9 +5,9 @@ pub(crate) struct Configuration {
pub(crate) input_ty: syn::Type,
pub(crate) value_ty: syn::Type,
pub(crate) cycle_strategy: CycleRecoveryStrategy,
pub(crate) backdate_fn: syn::ImplItemMethod,
pub(crate) execute_fn: syn::ImplItemMethod,
pub(crate) recover_fn: syn::ImplItemMethod,
pub(crate) backdate_fn: syn::ImplItemFn,
pub(crate) execute_fn: syn::ImplItemFn,
pub(crate) recover_fn: syn::ImplItemFn,
}
impl Configuration {
@ -58,7 +58,7 @@ impl quote::ToTokens for CycleRecoveryStrategy {
/// Returns an appropriate definition for `should_backdate_value` depending on
/// whether this value is memoized or not.
pub(crate) fn should_backdate_value_fn(should_backdate: bool) -> syn::ImplItemMethod {
pub(crate) fn should_backdate_value_fn(should_backdate: bool) -> syn::ImplItemFn {
if should_backdate {
parse_quote! {
fn should_backdate_value(v1: &Self::Value<'_>, v2: &Self::Value<'_>) -> bool {
@ -76,7 +76,7 @@ pub(crate) fn should_backdate_value_fn(should_backdate: bool) -> syn::ImplItemMe
/// Returns an appropriate definition for `recover_from_cycle` for cases where
/// the cycle recovery is panic.
pub(crate) fn panic_cycle_recovery_fn() -> syn::ImplItemMethod {
pub(crate) fn panic_cycle_recovery_fn() -> syn::ImplItemFn {
parse_quote! {
fn recover_from_cycle<'db>(
_db: &'db salsa::function::DynDb<'db, Self>,

View file

@ -83,7 +83,7 @@ impl InputStruct {
let field_tys: Vec<_> = self.all_field_tys();
let field_clones: Vec<_> = self.all_fields().map(SalsaField::is_clone_field).collect();
let get_field_names: Vec<_> = self.all_get_field_names();
let field_getters: Vec<syn::ImplItemMethod> = field_indices.iter().zip(&get_field_names).zip(&field_vises).zip(&field_tys).zip(&field_clones).map(|((((field_index, get_field_name), field_vis), field_ty), is_clone_field)|
let field_getters: Vec<syn::ImplItemFn> = field_indices.iter().zip(&get_field_names).zip(&field_vises).zip(&field_tys).zip(&field_clones).map(|((((field_index, get_field_name), field_vis), field_ty), is_clone_field)|
if !*is_clone_field {
parse_quote_spanned! { get_field_name.span() =>
#field_vis fn #get_field_name<'db>(self, __db: &'db #db_dyn_ty) -> &'db #field_ty
@ -108,7 +108,7 @@ impl InputStruct {
// setters
let set_field_names = self.all_set_field_names();
let field_setters: Vec<syn::ImplItemMethod> = field_indices.iter()
let field_setters: Vec<syn::ImplItemFn> = field_indices.iter()
.zip(&set_field_names)
.zip(&field_vises)
.zip(&field_tys)
@ -128,7 +128,7 @@ impl InputStruct {
let constructor_name = self.constructor_name();
let singleton = self.0.is_isingleton();
let constructor: syn::ImplItemMethod = if singleton {
let constructor: syn::ImplItemFn = if singleton {
parse_quote_spanned! { constructor_name.span() =>
/// Creates a new singleton input
///
@ -168,7 +168,7 @@ impl InputStruct {
);
if singleton {
let get: syn::ImplItemMethod = parse_quote! {
let get: syn::ImplItemFn = parse_quote! {
#[track_caller]
pub fn get(__db: &#db_dyn_ty) -> Self {
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db);
@ -177,7 +177,7 @@ impl InputStruct {
}
};
let try_get: syn::ImplItemMethod = parse_quote! {
let try_get: syn::ImplItemFn = parse_quote! {
#[track_caller]
pub fn try_get(__db: &#db_dyn_ty) -> Option<Self> {
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db);

View file

@ -187,7 +187,7 @@ impl InternedStruct {
let db_dyn_ty = self.db_dyn_ty();
let jar_ty = self.jar_ty();
let field_getters: Vec<syn::ImplItemMethod> = self
let field_getters: Vec<syn::ImplItemFn> = self
.all_fields()
.map(|field| {
let field_name = field.name();
@ -214,7 +214,7 @@ impl InternedStruct {
let field_tys = self.all_field_tys();
let data_ident = self.data_ident();
let constructor_name = self.constructor_name();
let new_method: syn::ImplItemMethod = parse_quote_spanned! { constructor_name.span() =>
let new_method: syn::ImplItemFn = parse_quote_spanned! { constructor_name.span() =>
#vis fn #constructor_name(
db: &#db_dyn_ty,
#(#field_names: #field_tys,)*
@ -261,7 +261,7 @@ impl InternedStruct {
let db_dyn_ty = self.db_dyn_ty();
let jar_ty = self.jar_ty();
let field_getters: Vec<syn::ImplItemMethod> = self
let field_getters: Vec<syn::ImplItemFn> = self
.all_fields()
.map(|field| {
let field_name = field.name();
@ -292,7 +292,7 @@ impl InternedStruct {
let field_tys = self.all_field_tys();
let data_ident = self.data_ident();
let constructor_name = self.constructor_name();
let new_method: syn::ImplItemMethod = parse_quote_spanned! { constructor_name.span() =>
let new_method: syn::ImplItemFn = parse_quote_spanned! { constructor_name.span() =>
#vis fn #constructor_name(
db: &#db_dyn_ty,
#(#field_names: #field_tys,)*

View file

@ -1,4 +1,5 @@
use proc_macro2::Literal;
use proc_macro2::extra::DelimSpan;
use proc_macro2::{Delimiter, Group, Literal, TokenStream};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::visit_mut::VisitMut;
@ -166,7 +167,7 @@ fn generate_fields(input: &ItemStruct) -> FieldsUnnamed {
},
syn::Fields::Unnamed(f) => f.paren_token,
syn::Fields::Unit => syn::token::Paren {
span: input.ident.span(),
span: to_delim_span(input),
},
};
@ -175,3 +176,9 @@ fn generate_fields(input: &ItemStruct) -> FieldsUnnamed {
unnamed: output_fields,
}
}
fn to_delim_span(s: &impl Spanned) -> DelimSpan {
let mut group = Group::new(Delimiter::None, TokenStream::new());
group.set_span(s.span());
group.delim_span()
}

View file

@ -53,7 +53,7 @@ const BANNED_FIELD_NAMES: &[&str] = &["from", "new"];
/// Classifies the kind of field stored in this salsa
/// struct.
#[derive(Debug, PartialEq, Eq)]
#[derive(PartialEq, Eq)]
pub enum TheStructKind {
/// Stores an "id"
Id,
@ -62,6 +62,15 @@ pub enum TheStructKind {
Pointer(syn::Lifetime),
}
impl std::fmt::Debug for TheStructKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TheStructKind::Id => write!(f, "Id"),
TheStructKind::Pointer(lt) => write!(f, "Pointer({lt})"),
}
}
}
impl<A: AllowedOptions> SalsaStruct<A> {
pub(crate) fn new(
args: proc_macro::TokenStream,
@ -164,7 +173,7 @@ impl<A: AllowedOptions> SalsaStruct<A> {
.attrs
.iter()
.map(|attr| {
if attr.path.is_ident("customize") {
if attr.path().is_ident("customize") {
// FIXME: this should be a comma separated list but I couldn't
// be bothered to remember how syn does this.
let args: syn::Ident = attr.parse_args()?;
@ -294,8 +303,8 @@ impl<A: AllowedOptions> SalsaStruct<A> {
.struct_item
.attrs
.iter()
.filter(|attr| !attr.path.is_ident("derive"))
.filter(|attr| !attr.path.is_ident("customize"))
.filter(|attr| !attr.path().is_ident("derive"))
.filter(|attr| !attr.path().is_ident("customize"))
.collect();
parse_quote_spanned! { ident.span() =>
@ -330,8 +339,8 @@ impl<A: AllowedOptions> SalsaStruct<A> {
.struct_item
.attrs
.iter()
.filter(|attr| !attr.path.is_ident("derive"))
.filter(|attr| !attr.path.is_ident("customize"))
.filter(|attr| !attr.path().is_ident("derive"))
.filter(|attr| !attr.path().is_ident("customize"))
.collect();
let module = &self.module;
@ -600,7 +609,7 @@ impl SalsaField {
// Scan the attributes and look for the salsa attributes:
for attr in &field.attrs {
for (fa, func) in FIELD_OPTION_ATTRIBUTES {
if attr.path.is_ident(fa) {
if attr.path().is_ident(fa) {
func(attr, &mut result);
}
}

View file

@ -1,4 +1,4 @@
use proc_macro2::{Literal, TokenStream};
use proc_macro2::{Literal, Span, TokenStream};
use syn::spanned::Spanned;
use syn::visit_mut::VisitMut;
use syn::{ReturnType, Token};
@ -119,23 +119,23 @@ pub(crate) fn tracked_impl(
.iter_mut()
.filter_map(|item| {
let item_method = match item {
syn::ImplItem::Method(item_method) => item_method,
syn::ImplItem::Fn(item_method) => item_method,
_ => return None,
};
let salsa_tracked_attr = item_method.attrs.iter().position(|attr| {
let path = &attr.path.segments;
let path = &attr.path().segments;
path.len() == 2
&& path[0].arguments == syn::PathArguments::None
&& path[0].arguments.is_none()
&& path[0].ident == "salsa"
&& path[1].arguments == syn::PathArguments::None
&& path[1].arguments.is_none()
&& path[1].ident == "tracked"
})?;
let salsa_tracked_attr = item_method.attrs.remove(salsa_tracked_attr);
let inner_args = if !salsa_tracked_attr.tokens.is_empty() {
salsa_tracked_attr.parse_args()
} else {
Ok(FnArgs::default())
let inner_args = match salsa_tracked_attr.meta {
syn::Meta::Path(_) => Ok(FnArgs::default()),
syn::Meta::List(_) | syn::Meta::NameValue(_) => salsa_tracked_attr.parse_args(),
};
let inner_args = match inner_args {
Ok(inner_args) => inner_args,
Err(err) => return Some(Err(err)),
@ -194,7 +194,7 @@ impl crate::options::AllowedOptions for TrackedImpl {
fn tracked_method(
outer_args: &ImplArgs,
mut args: FnArgs,
item_method: &mut syn::ImplItemMethod,
item_method: &mut syn::ImplItemFn,
self_type: &syn::TypePath,
name: &str,
) -> syn::Result<TokenStream> {
@ -670,7 +670,7 @@ fn setter_fn(
args: &FnArgs,
item_fn: &syn::ItemFn,
config_ty: &syn::Type,
) -> syn::Result<syn::ImplItemMethod> {
) -> syn::Result<syn::ImplItemFn> {
// The setter has *always* the same signature as the original:
// but it takes a value arg and has no return type.
let jar_ty = args.jar_ty();
@ -691,7 +691,7 @@ fn setter_fn(
let value_arg = syn::Ident::new("__value", item_fn.sig.output.span());
setter_sig.inputs.push(parse_quote!(#value_arg: #value_ty));
setter_sig.output = ReturnType::Default;
Ok(syn::ImplItemMethod {
Ok(syn::ImplItemFn {
attrs: vec![],
vis: item_fn.vis.clone(),
defaultness: None,
@ -722,7 +722,7 @@ fn setter_fn(
fn set_lru_capacity_fn(
args: &FnArgs,
config_ty: &syn::Type,
) -> syn::Result<Option<syn::ImplItemMethod>> {
) -> syn::Result<Option<syn::ImplItemFn>> {
if args.lru.is_none() {
return Ok(None);
}
@ -744,7 +744,7 @@ fn specify_fn(
args: &FnArgs,
item_fn: &syn::ItemFn,
config_ty: &syn::Type,
) -> syn::Result<Option<syn::ImplItemMethod>> {
) -> syn::Result<Option<syn::ImplItemFn>> {
if args.specify.is_none() {
return Ok(None);
}
@ -759,7 +759,7 @@ fn specify_fn(
let value_arg = syn::Ident::new("__value", item_fn.sig.output.span());
setter_sig.inputs.push(parse_quote!(#value_arg: #value_ty));
setter_sig.output = ReturnType::Default;
Ok(Some(syn::ImplItemMethod {
Ok(Some(syn::ImplItemFn {
attrs: vec![],
vis: item_fn.vis.clone(),
defaultness: None,
@ -784,7 +784,10 @@ fn make_fn_return_ref(fn_sig: &mut syn::Signature) -> syn::Result<()> {
let (db_lifetime, _) = db_lifetime_and_ty(fn_sig)?;
let (right_arrow, elem) = match fn_sig.output.clone() {
ReturnType::Default => (syn::Token![->](fn_sig.paren_token.span), parse_quote!(())),
ReturnType::Default => (
syn::Token![->]([Span::call_site(), Span::call_site()]),
parse_quote!(()),
),
ReturnType::Type(rarrow, ty) => (rarrow, ty),
};
@ -821,7 +824,7 @@ fn db_lifetime_and_ty(func: &mut syn::Signature) -> syn::Result<(syn::Lifetime,
let ident = syn::Ident::new("__db", and_token_span);
func.generics.params.insert(
0,
syn::LifetimeDef {
syn::LifetimeParam {
attrs: vec![],
lifetime: syn::Lifetime {
apostrophe: and_token_span,

View file

@ -173,7 +173,7 @@ impl TrackedStruct {
let field_tys: Vec<_> = self.all_fields().map(SalsaField::ty).collect();
let field_get_names: Vec<_> = self.all_fields().map(SalsaField::get_name).collect();
let field_clones: Vec<_> = self.all_fields().map(SalsaField::is_clone_field).collect();
let field_getters: Vec<syn::ImplItemMethod> = field_indices.iter().zip(&field_get_names).zip(&field_tys).zip(&field_vises).zip(&field_clones).map(|((((field_index, field_get_name), field_ty), field_vis), is_clone_field)|
let field_getters: Vec<syn::ImplItemFn> = field_indices.iter().zip(&field_get_names).zip(&field_tys).zip(&field_vises).zip(&field_clones).map(|((((field_index, field_get_name), field_ty), field_vis), is_clone_field)|
match the_kind {
TheStructKind::Id => {
if !*is_clone_field {