Skip to content

Commit

Permalink
Update to syn 2
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Mar 18, 2023
1 parent 15fd282 commit 032c150
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 92 deletions.
2 changes: 1 addition & 1 deletion .clippy.toml
@@ -1 +1 @@
msrv = "1.39.0"
msrv = "1.56.0"
11 changes: 0 additions & 11 deletions .github/workflows/ci.yml
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Expand Up @@ -9,15 +9,15 @@ 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

[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"
Expand Down
121 changes: 51 additions & 70 deletions src/expand.rs
Expand Up @@ -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,
};

Expand All @@ -36,7 +36,7 @@ enum Context<'a> {
}

impl Context<'_> {
fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator<Item = &'a LifetimeDef> {
fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator<Item = &'a LifetimeParam> {
let generics = match self {
Context::Trait { generics, .. } => generics,
Context::Impl { impl_generics, .. } => impl_generics,
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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<Self>
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<Self>
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| {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/lifetime.rs
Expand Up @@ -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);
}
}

Expand Down
8 changes: 1 addition & 7 deletions src/receiver.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion tests/test.rs
Expand Up @@ -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) {
Expand Down

0 comments on commit 032c150

Please sign in to comment.