1 use proc_macro2::{Ident, Span, TokenStream};
2 use quote::quote_spanned;
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
spanned_path(&self, span: Span) -> TokenStream38 pub fn spanned_path(&self, span: Span) -> TokenStream {
39 let ident = Ident::new(self.as_str(), span);
40 quote_spanned!(span=> ::core::marker::#ident)
41 }
42 }
43
44 impl PartialEq<InferredBound> for Ident {
eq(&self, bound: &InferredBound) -> bool45 fn eq(&self, bound: &InferredBound) -> bool {
46 self == bound.as_str()
47 }
48 }
49