1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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()
}
}