#![doc = include_str!("../README.md")]
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::ToTokens;
use syn::{
parse_macro_input,
punctuated::{Pair, Punctuated},
token::{Bang, Brace, Comma, Const, Default as DefaultKW, For, Gt, Impl, Lt, Paren, Unsafe},
Abi, Attribute, Block, BoundLifetimes, ConstParam, FnArg, Ident, ImplItemConst, ImplItemMacro,
ItemImpl, Lifetime, LifetimeDef, Path, PredicateEq, PredicateLifetime, ReturnType, Token, Type,
Variadic, Visibility,
};
use syn::ImplItemType;
mod from;
mod parse;
mod to_tokens;
pub(crate) struct ItemConstImpl {
attrs: Vec<Attribute>,
defaultness: Option<DefaultKW>,
unsafety: Option<Unsafe>,
impl_token: Impl,
generics: Generics,
constness: Option<Const>,
trait_: Option<(Option<Bang>, Path, For)>,
self_ty: Box<Type>,
brace_token: Brace,
items: Vec<ImplItem>,
}
pub(crate) struct Signature {
pub constness: Option<Token![const]>,
pub asyncness: Option<Token![async]>,
pub unsafety: Option<Token![unsafe]>,
pub abi: Option<Abi>,
pub fn_token: Token![fn],
pub ident: Ident,
pub generics: Generics,
pub paren_token: syn::token::Paren,
pub inputs: Punctuated<FnArg, Token![,]>,
pub variadic: Option<Variadic>,
pub output: ReturnType,
}
pub(crate) struct ImplItemMethod {
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub defaultness: Option<Token![default]>,
pub sig: Signature,
pub block: Block,
}
pub(crate) enum ImplItem {
Const(ImplItemConst),
Method(ImplItemMethod),
Type(ImplItemType),
Macro(ImplItemMacro),
Verbatim(TokenStream2),
}
#[derive(Default)]
pub(crate) struct Generics {
lt_token: Option<Lt>,
params: Punctuated<GenericParam, Comma>,
gt_token: Option<Gt>,
where_clause: Option<WhereClause>,
}
#[allow(clippy::large_enum_variant)]
pub(crate) enum GenericParam {
Type(TypeParam),
Lifetime(LifetimeDef),
Const(ConstParam),
}
struct TypeParam {
pub attrs: Vec<Attribute>,
pub ident: Ident,
pub colon_token: Option<Token![:]>,
pub bounds: Punctuated<TypeParamBound, Token![+]>,
pub eq_token: Option<Token![=]>,
pub default: Option<Type>,
}
pub(crate) enum TypeParamBound {
Trait(TraitBound),
Lifetime(Lifetime),
}
pub(crate) struct TraitBound {
pub paren_token: Option<Paren>,
pub modifier: TraitBoundModifier,
pub lifetimes: Option<BoundLifetimes>,
pub path: Path,
}
pub(crate) enum TraitBoundModifier {
None,
Maybe(Token![?]),
TildeConst(TildeConst),
}
pub(crate) struct TildeConst {
tilde: Token![~],
const_: Token![const],
}
pub(crate) struct PredicateType {
pub lifetimes: Option<BoundLifetimes>,
pub bounded_ty: Type,
pub colon_token: Token![:],
pub bounds: Punctuated<TypeParamBound, Token![+]>,
}
pub(crate) enum WherePredicate {
Type(PredicateType),
Lifetime(PredicateLifetime),
#[allow(dead_code)]
Eq(PredicateEq),
}
pub(crate) struct WhereClause {
pub where_token: Token![where],
pub predicates: Punctuated<WherePredicate, Token![,]>,
}
pub(crate) struct TokensOrDefault<'a, T: 'a>(pub &'a Option<T>);
#[proc_macro]
pub fn unconst_trait_impl(item: TokenStream) -> TokenStream {
let item_const_impl = parse_macro_input!(item as ItemConstImpl);
let item_impl: ItemImpl = item_const_impl.into();
item_impl.to_token_stream().into()
}