aboutsummaryrefslogtreecommitdiff
path: root/src/expand.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/expand.rs')
-rw-r--r--src/expand.rs130
1 files changed, 52 insertions, 78 deletions
diff --git a/src/expand.rs b/src/expand.rs
index 88338db..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<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,
@@ -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;
@@ -80,13 +80,6 @@ pub fn expand(input: &mut Item, is_local: bool) {
}
}
Item::Impl(input) => {
- let mut lifetimes = CollectLifetimes::new("'impl");
- lifetimes.visit_type_mut(&mut *input.self_ty);
- lifetimes.visit_path_mut(&mut input.trait_.as_mut().unwrap().1);
- let params = &input.generics.params;
- let elided = lifetimes.elided;
- input.generics.params = parse_quote!(#(#elided,)* #params);
-
let mut associated_type_impl_traits = Set::new();
for inner in &input.items {
if let ImplItem::Type(assoc) = inner {
@@ -101,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;
@@ -167,7 +160,7 @@ fn transform_sig(
ReturnType::Type(arrow, ret) => (*arrow, quote!(#ret)),
};
- let mut lifetimes = CollectLifetimes::new("'life");
+ let mut lifetimes = CollectLifetimes::new();
for arg in sig.inputs.iter_mut() {
match arg {
FnArg::Receiver(arg) => lifetimes.visit_receiver_mut(arg),
@@ -215,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 {
@@ -230,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| {
@@ -293,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);
}
@@ -373,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);