1 use proc_macro2::{Ident, Span, TokenStream};
2 use quote::{quote, ToTokens};
3 use syn::punctuated::Punctuated;
4 use syn::{Token, TypeParamBound};
5 
6 pub type Supertraits = Punctuated<TypeParamBound, Token![+]>;
7 
8 pub enum InferredBound {
9     Send,
10     Sync,
11 }
12 
has_bound(supertraits: &Supertraits, bound: &InferredBound) -> bool13 pub fn has_bound(supertraits: &Supertraits, bound: &InferredBound) -> bool {
14     for supertrait in supertraits {
15         if let TypeParamBound::Trait(supertrait) = supertrait {
16             if supertrait.path.is_ident(bound)
17                 || supertrait.path.segments.len() == 3
18                     && (supertrait.path.segments[0].ident == "std"
19                         || supertrait.path.segments[0].ident == "core")
20                     && supertrait.path.segments[1].ident == "marker"
21                     && supertrait.path.segments[2].ident == *bound
22             {
23                 return true;
24             }
25         }
26     }
27     false
28 }
29 
30 impl InferredBound {
as_str(&self) -> &str31     fn as_str(&self) -> &str {
32         match self {
33             InferredBound::Send => "Send",
34             InferredBound::Sync => "Sync",
35         }
36     }
37 }
38 
39 impl ToTokens for InferredBound {
to_tokens(&self, tokens: &mut TokenStream)40     fn to_tokens(&self, tokens: &mut TokenStream) {
41         let ident = Ident::new(self.as_str(), Span::call_site());
42         quote!(::core::marker::#ident).to_tokens(tokens);
43     }
44 }
45 
46 impl PartialEq<InferredBound> for Ident {
eq(&self, bound: &InferredBound) -> bool47     fn eq(&self, bound: &InferredBound) -> bool {
48         self == bound.as_str()
49     }
50 }
51