Skip to content

Commit

Permalink
Merge pull request #221 from dtolnay/bound
Browse files Browse the repository at this point in the history
Create enum for the different possible inferred bounds
  • Loading branch information
dtolnay committed Nov 29, 2022
2 parents 4bcf6d7 + fd5b9d4 commit cfa9c10
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 23 deletions.
46 changes: 46 additions & 0 deletions src/bound.rs
@@ -0,0 +1,46 @@
use proc_macro2::{Ident, Span};
use syn::punctuated::Punctuated;
use syn::{Token, TypeParamBound};

pub type Supertraits = Punctuated<TypeParamBound, Token![+]>;

pub enum InferredBound {
Send,
Sync,
}

pub fn has_bound(supertraits: &Supertraits, bound: &InferredBound) -> bool {
for supertrait in supertraits {
if let TypeParamBound::Trait(supertrait) = supertrait {
if supertrait.path.is_ident(bound)
|| supertrait.path.segments.len() == 3
&& (supertrait.path.segments[0].ident == "std"
|| supertrait.path.segments[0].ident == "core")
&& supertrait.path.segments[1].ident == "marker"
&& supertrait.path.segments[2].ident == *bound
{
return true;
}
}
}
false
}

impl InferredBound {
fn as_str(&self) -> &str {
match self {
InferredBound::Send => "Send",
InferredBound::Sync => "Sync",
}
}

pub fn spanned_ident(&self, span: Span) -> Ident {
Ident::new(self.as_str(), span)
}
}

impl PartialEq<InferredBound> for Ident {
fn eq(&self, bound: &InferredBound) -> bool {
self == bound.as_str()
}
}
29 changes: 6 additions & 23 deletions src/expand.rs
@@ -1,3 +1,4 @@
use crate::bound::{has_bound, InferredBound, Supertraits};
use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes};
use crate::parse::Item;
use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
Expand All @@ -10,7 +11,7 @@ use syn::visit_mut::{self, VisitMut};
use syn::{
parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericParam, Generics, Ident,
ImplItem, Lifetime, LifetimeDef, Pat, PatIdent, Receiver, ReturnType, Signature, Stmt, Token,
TraitItem, Type, TypeParamBound, TypePath, WhereClause,
TraitItem, Type, TypePath, WhereClause,
};

impl ToTokens for Item {
Expand Down Expand Up @@ -51,8 +52,6 @@ impl Context<'_> {
}
}

type Supertraits = Punctuated<TypeParamBound, Token![+]>;

pub fn expand(input: &mut Item, is_local: bool) {
match input {
Item::Trait(input) => {
Expand Down Expand Up @@ -235,7 +234,7 @@ fn transform_sig(
reference: Some(_),
mutability: None,
..
})) => Ident::new("Sync", default_span),
})) => InferredBound::Sync,
Some(FnArg::Typed(arg))
if match (arg.pat.as_ref(), arg.ty.as_ref()) {
(Pat::Ident(pat), Type::Reference(ty)) => {
Expand All @@ -244,9 +243,9 @@ fn transform_sig(
_ => false,
} =>
{
Ident::new("Sync", default_span)
InferredBound::Sync
}
_ => Ident::new("Send", default_span),
_ => InferredBound::Send,
};

let assume_bound = match context {
Expand All @@ -258,6 +257,7 @@ fn transform_sig(
where_clause.predicates.push(if assume_bound || is_local {
parse_quote_spanned!(default_span=> Self: 'async_trait)
} else {
let bound = bound.spanned_ident(default_span);
parse_quote_spanned!(default_span=> Self: ::core::marker::#bound + 'async_trait)
});
}
Expand Down Expand Up @@ -402,23 +402,6 @@ fn positional_arg(i: usize, pat: &Pat) -> Ident {
format_ident!("__arg{}", i, span = span)
}

fn has_bound(supertraits: &Supertraits, marker: &Ident) -> bool {
for bound in supertraits {
if let TypeParamBound::Trait(bound) = bound {
if bound.path.is_ident(marker)
|| bound.path.segments.len() == 3
&& (bound.path.segments[0].ident == "std"
|| bound.path.segments[0].ident == "core")
&& bound.path.segments[1].ident == "marker"
&& bound.path.segments[2].ident == *marker
{
return true;
}
}
}
false
}

fn contains_associated_type_impl_trait(context: Context, ret: &mut Type) -> bool {
struct AssociatedTypeImplTraits<'a> {
set: &'a Set<Ident>,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Expand Up @@ -318,6 +318,7 @@
extern crate proc_macro;

mod args;
mod bound;
mod expand;
mod lifetime;
mod parse;
Expand Down

0 comments on commit cfa9c10

Please sign in to comment.