|  | use proc_macro2::{Ident, Span, TokenStream}; | 
|  | use quote::quote_spanned; | 
|  | 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_path(&self, span: Span) -> TokenStream { | 
|  | let ident = Ident::new(self.as_str(), span); | 
|  | quote_spanned!(span=> ::core::marker::#ident) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl PartialEq<InferredBound> for Ident { | 
|  | fn eq(&self, bound: &InferredBound) -> bool { | 
|  | self == bound.as_str() | 
|  | } | 
|  | } |