48 lines
1.3 KiB
Rust
48 lines
1.3 KiB
Rust
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()
|
|
}
|
|
}
|