From 032c1506e3787847a52cba311aa9459c49a9a6ba Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 11 Feb 2023 20:02:59 -0800 Subject: [PATCH] Update to syn 2 --- .clippy.toml | 2 +- .github/workflows/ci.yml | 11 ---- Cargo.toml | 4 +- src/expand.rs | 121 +++++++++++++++++---------------------- src/lifetime.rs | 2 + src/receiver.rs | 8 +-- tests/test.rs | 1 - 7 files changed, 57 insertions(+), 92 deletions(-) diff --git a/.clippy.toml b/.clippy.toml index 21a08b0..0d369b5 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1 +1 @@ -msrv = "1.39.0" +msrv = "1.56.0" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51fdd49..6ac696a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,17 +39,6 @@ jobs: if: matrix.rust == 'nightly' - run: cargo test - msrv: - name: Rust 1.39.0 - needs: pre_ci - if: needs.pre_ci.outputs.continue - runs-on: ubuntu-latest - timeout-minutes: 45 - steps: - - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@1.39.0 - - run: cargo check - clippy: name: Clippy runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 152ec78..8a30a35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" keywords = ["async"] license = "MIT OR Apache-2.0" repository = "https://github.com/dtolnay/async-trait" -rust-version = "1.39" +rust-version = "1.56" [lib] proc-macro = true @@ -17,7 +17,7 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = { version = "1.0.96", features = ["full", "visit-mut"] } +syn = { version = "2.0", features = ["full", "visit-mut"] } [dev-dependencies] futures = "0.3" diff --git a/src/expand.rs b/src/expand.rs index 2499177..362ba78 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -10,7 +10,7 @@ use syn::punctuated::Punctuated; use syn::visit_mut::{self, VisitMut}; use syn::{ parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericArgument, GenericParam, - Generics, Ident, ImplItem, Lifetime, LifetimeDef, Pat, PatIdent, PathArguments, Receiver, + Generics, Ident, ImplItem, Lifetime, LifetimeParam, Pat, PatIdent, PathArguments, Receiver, ReturnType, Signature, Stmt, Token, TraitItem, Type, TypePath, WhereClause, }; @@ -36,7 +36,7 @@ enum Context<'a> { } impl Context<'_> { - fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator { + fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator { let generics = match self { Context::Trait { generics, .. } => generics, Context::Impl { impl_generics, .. } => impl_generics, @@ -60,7 +60,7 @@ pub fn expand(input: &mut Item, is_local: bool) { supertraits: &input.supertraits, }; for inner in &mut input.items { - if let TraitItem::Method(method) = inner { + if let TraitItem::Fn(method) = inner { let sig = &mut method.sig; if sig.asyncness.is_some() { let block = &mut method.default; @@ -94,7 +94,7 @@ pub fn expand(input: &mut Item, is_local: bool) { associated_type_impl_traits: &associated_type_impl_traits, }; for inner in &mut input.items { - if let ImplItem::Method(method) = inner { + if let ImplItem::Fn(method) = inner { let sig = &mut method.sig; if sig.asyncness.is_some() { let block = &mut method.block; @@ -208,7 +208,7 @@ fn transform_sig( sig.generics.lt_token = Some(Token![<](sig.ident.span())); } if sig.generics.gt_token.is_none() { - sig.generics.gt_token = Some(Token![>](sig.paren_token.span)); + sig.generics.gt_token = Some(Token![>](sig.paren_token.span.join())); } for elided in lifetimes.elided { @@ -223,46 +223,35 @@ fn transform_sig( .push(parse_quote_spanned!(default_span=> 'async_trait)); if has_self { - let bounds: &[InferredBound] = match sig.inputs.iter().next() { - Some(FnArg::Receiver(Receiver { - reference: Some(_), - mutability: None, - .. - })) => &[InferredBound::Sync], - Some(FnArg::Typed(arg)) - if match arg.pat.as_ref() { - Pat::Ident(pat) => pat.ident == "self", - _ => false, - } => - { - match arg.ty.as_ref() { - // self: &Self - Type::Reference(ty) if ty.mutability.is_none() => &[InferredBound::Sync], - // self: Arc - Type::Path(ty) - if { - let segment = ty.path.segments.last().unwrap(); - segment.ident == "Arc" - && match &segment.arguments { - PathArguments::AngleBracketed(arguments) => { - arguments.args.len() == 1 - && match &arguments.args[0] { - GenericArgument::Type(Type::Path(arg)) => { - arg.path.is_ident("Self") - } - _ => false, + let bounds: &[InferredBound] = if let Some(receiver) = sig.receiver() { + match receiver.ty.as_ref() { + // self: &Self + Type::Reference(ty) if ty.mutability.is_none() => &[InferredBound::Sync], + // self: Arc + Type::Path(ty) + if { + let segment = ty.path.segments.last().unwrap(); + segment.ident == "Arc" + && match &segment.arguments { + PathArguments::AngleBracketed(arguments) => { + arguments.args.len() == 1 + && match &arguments.args[0] { + GenericArgument::Type(Type::Path(arg)) => { + arg.path.is_ident("Self") } - } - _ => false, + _ => false, + } } - } => - { - &[InferredBound::Sync, InferredBound::Send] - } - _ => &[InferredBound::Send], + _ => false, + } + } => + { + &[InferredBound::Sync, InferredBound::Send] } + _ => &[InferredBound::Send], } - _ => &[InferredBound::Send], + } else { + &[InferredBound::Send] }; let bounds = bounds.iter().filter_map(|bound| { @@ -286,24 +275,24 @@ fn transform_sig( for (i, arg) in sig.inputs.iter_mut().enumerate() { match arg { - FnArg::Receiver(Receiver { - reference: Some(_), .. - }) => {} - FnArg::Receiver(arg) => arg.mutability = None, + FnArg::Receiver(receiver) => { + if receiver.reference.is_none() { + receiver.mutability = None; + } + } FnArg::Typed(arg) => { - let type_is_reference = match *arg.ty { - Type::Reference(_) => true, - _ => false, - }; - if let Pat::Ident(pat) = &mut *arg.pat { - if pat.ident == "self" || !type_is_reference { + if match *arg.ty { + Type::Reference(_) => false, + _ => true, + } { + if let Pat::Ident(pat) = &mut *arg.pat { pat.by_ref = None; pat.mutability = None; + } else { + let positional = positional_arg(i, &arg.pat); + let m = mut_pat(&mut arg.pat); + arg.pat = parse_quote!(#m #positional); } - } else if !type_is_reference { - let positional = positional_arg(i, &arg.pat); - let m = mut_pat(&mut arg.pat); - arg.pat = parse_quote!(#m #positional); } AddLifetimeToImplTrait.visit_type_mut(&mut arg.ty); } @@ -366,26 +355,18 @@ fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) { // the parameter, forward it to the variable. // // This is currently not applied to the `self` parameter. - let attrs = arg.attrs.iter().filter(|attr| attr.path.is_ident("cfg")); + let attrs = arg.attrs.iter().filter(|attr| attr.path().is_ident("cfg")); - if let Pat::Ident(PatIdent { + if let Type::Reference(_) = *arg.ty { + quote!() + } else if let Pat::Ident(PatIdent { ident, mutability, .. }) = &*arg.pat { - if ident == "self" { - self_span = Some(ident.span()); - let prefixed = Ident::new("__self", ident.span()); - quote!(let #mutability #prefixed = #ident;) - } else if let Type::Reference(_) = *arg.ty { - quote!() - } else { - quote! { - #(#attrs)* - let #mutability #ident = #ident; - } + quote! { + #(#attrs)* + let #mutability #ident = #ident; } - } else if let Type::Reference(_) = *arg.ty { - quote!() } else { let pat = &arg.pat; let ident = positional_arg(i, pat); diff --git a/src/lifetime.rs b/src/lifetime.rs index 1e5a658..a7babfb 100644 --- a/src/lifetime.rs +++ b/src/lifetime.rs @@ -46,6 +46,8 @@ impl VisitMut for CollectLifetimes { fn visit_receiver_mut(&mut self, arg: &mut Receiver) { if let Some((reference, lifetime)) = &mut arg.reference { self.visit_opt_lifetime(*reference, lifetime); + } else { + visit_mut::visit_type_mut(self, &mut arg.ty); } } diff --git a/src/receiver.rs b/src/receiver.rs index 2230db6..6de5090 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -2,8 +2,7 @@ use proc_macro2::{Group, Span, TokenStream, TokenTree}; use std::iter::FromIterator; use syn::visit_mut::{self, VisitMut}; use syn::{ - Block, ExprPath, Ident, Item, Macro, Pat, PatIdent, PatPath, Path, Receiver, Signature, Token, - TypePath, + Block, ExprPath, Ident, Item, Macro, Pat, PatIdent, Path, Receiver, Signature, Token, TypePath, }; pub fn has_self_in_sig(sig: &mut Signature) -> bool { @@ -60,11 +59,6 @@ impl VisitMut for HasSelf { visit_mut::visit_expr_path_mut(self, expr); } - fn visit_pat_path_mut(&mut self, pat: &mut PatPath) { - self.0 |= pat.path.segments[0].ident == "Self"; - visit_mut::visit_pat_path_mut(self, pat); - } - fn visit_type_path_mut(&mut self, ty: &mut TypePath) { self.0 |= ty.path.segments[0].ident == "Self"; visit_mut::visit_type_path_mut(self, ty); diff --git a/tests/test.rs b/tests/test.rs index 4fc46f0..f36618f 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -741,7 +741,6 @@ pub mod issue57 { // https://github.com/dtolnay/async-trait/issues/68 pub mod issue68 { - #[rustversion::since(1.40)] // procedural macros cannot expand to macro definitions in 1.39. #[async_trait::async_trait] pub trait Example { async fn method(&self) {