diff --git a/Cargo.lock b/Cargo.lock index 2e50abc..23cdc34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -543,9 +543,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -647,9 +647,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.66" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 2cfa586..54de3a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ quote = "1.0.36" serde = { version = "1.0.202", features = ["derive"] } serde_json = { version = "1.0.117", features = ["preserve_order"] } sha2 = "0.10.8" -syn = { version = "2.0.66", features = ["full", "fold", "visit", "extra-traits"] } +syn = { version = "2.0.93", features = ["full", "fold", "visit", "extra-traits"] } tempfile = "3.10.1" thiserror = "1.0.61" trybuild = "1.0" diff --git a/crates/fayalite-proc-macros-impl/src/lib.rs b/crates/fayalite-proc-macros-impl/src/lib.rs index d7f2752..1b1b61f 100644 --- a/crates/fayalite-proc-macros-impl/src/lib.rs +++ b/crates/fayalite-proc-macros-impl/src/lib.rs @@ -66,6 +66,7 @@ mod kw { }; } + custom_keyword!(__evaluated_cfgs); custom_keyword!(all); custom_keyword!(any); custom_keyword!(cfg); @@ -1022,6 +1023,12 @@ pub(crate) struct Cfg { trailing_comma: Option, } +impl Cfg { + fn parse_meta(meta: &Meta) -> syn::Result { + syn::parse2(meta.to_token_stream()) + } +} + impl ToTokens for Cfg { fn to_tokens(&self, tokens: &mut TokenStream) { let Self { @@ -1068,6 +1075,9 @@ impl CfgAttr { trailing_comma: None, } } + fn parse_meta(meta: &Meta) -> syn::Result { + syn::parse2(meta.to_token_stream()) + } } impl Parse for CfgAttr { @@ -1105,6 +1115,16 @@ pub(crate) struct Cfgs { pub(crate) cfgs_list: Vec, } +impl Default for Cfgs { + fn default() -> Self { + Self { + bracket: Default::default(), + cfgs_map: Default::default(), + cfgs_list: Default::default(), + } + } +} + impl Cfgs { fn insert_cfg(&mut self, cfg: Cfg, value: T) { match self.cfgs_map.entry(cfg) { @@ -1125,10 +1145,11 @@ impl Parse for Cfgs { let mut cfgs_list = Vec::new(); for CfgAndValue { cfg, - eq_token: _, + eq_token, value, } in contents.call(Punctuated::::parse_terminated)? { + let _ = eq_token; match cfgs_map.entry(cfg) { Entry::Occupied(_) => {} Entry::Vacant(entry) => { @@ -1184,7 +1205,44 @@ impl ToTokens for Cfgs<()> { } } -fn handle_top_level_attr(item: Item) -> syn::Result { +fn hdl_main( + kw: impl CustomToken, + attr: TokenStream, + item: TokenStream, +) -> syn::Result { + let (evaluated_cfgs, attr): (_, TokenStream) = Parser::parse2( + |input: ParseStream| { + if input.peek(Bracket) && input.peek2(kw::__evaluated_cfgs) { + let cfgs = input.parse()?; + let _: kw::__evaluated_cfgs = input.parse()?; + Ok((Some(cfgs), input.parse()?)) + } else { + Ok((None, input.parse()?)) + } + }, + attr, + )?; + let cfgs = if let Some(cfgs) = evaluated_cfgs { + cfgs + } else { + let cfgs = process_cfg::collect_cfgs(syn::parse2(item.clone())?)?; + if cfgs.cfgs_list.is_empty() { + Cfgs::default() + } else { + let key = kw::__evaluated_cfgs::default(); + return Ok(quote! { + ::fayalite::__cfg_expansion_helper! { + [] + #cfgs + #[::fayalite::#kw:(#key #attr)] { #item } + } + }); + } + }; + let item = syn::parse2(quote! { #[#kw(#attr)] #item })?; + let Some(item) = process_cfg::process_cfgs(item, cfgs)? else { + return Ok(TokenStream::new()); + }; match item { Item::Enum(item) => hdl_enum::hdl_enum(item), Item::Struct(item) => hdl_bundle::hdl_bundle(item), @@ -1197,39 +1255,10 @@ fn handle_top_level_attr(item: Item) -> syn::Result { } } -fn generate_cfg_expansion_tokens(input: TokenStream) -> syn::Result { - let item = syn::parse2::(input)?; - let cfgs = process_cfg::collect_cfgs(item.clone())?; - Ok(quote! { - ::fayalite::__cfg_expansion_helper! { - [] - #cfgs - ::fayalite::__after_cfg_expansion { #item } - } - }) -} - pub fn hdl_module(attr: TokenStream, item: TokenStream) -> syn::Result { - let kw = kw::hdl_module::default(); - generate_cfg_expansion_tokens(quote! { #[#kw(#attr)] #item }) + hdl_main(kw::hdl_module::default(), attr, item) } pub fn hdl_attr(attr: TokenStream, item: TokenStream) -> syn::Result { - let kw = kw::hdl::default(); - generate_cfg_expansion_tokens(quote! { #[#kw(#attr)] #item }) -} - -pub fn after_cfg_expansion(input: TokenStream) -> syn::Result { - syn::parse::Parser::parse2( - |input: ParseStream| -> syn::Result { - let cfgs = input.parse()?; - let item = input.parse()?; - let item = process_cfg::process_cfgs(item, cfgs)?; - Ok(item - .map(handle_top_level_attr) - .transpose()? - .unwrap_or_default()) - }, - input, - ) + hdl_main(kw::hdl::default(), attr, item) } diff --git a/crates/fayalite-proc-macros-impl/src/process_cfg.rs b/crates/fayalite-proc-macros-impl/src/process_cfg.rs index 06193cc..5cff08f 100644 --- a/crates/fayalite-proc-macros-impl/src/process_cfg.rs +++ b/crates/fayalite-proc-macros-impl/src/process_cfg.rs @@ -2,13 +2,11 @@ // See Notices.txt for copyright information use crate::{Cfg, CfgAttr, Cfgs, Errors}; -use std::{ - collections::{HashMap, VecDeque}, - marker::PhantomData, -}; +use proc_macro2::Ident; +use std::{collections::VecDeque, marker::PhantomData}; use syn::{ punctuated::{Pair, Punctuated}, - Attribute, Ident, Token, + Token, }; struct State { @@ -57,23 +55,26 @@ impl State

{ ) } #[must_use] - fn eval_cfgs(&mut self, mut attrs: Vec) -> Option, P>> { + fn eval_cfgs( + &mut self, + mut attrs: Vec, + ) -> Option, P>> { let mut queue = VecDeque::from(attrs); attrs = Vec::with_capacity(queue.len()); // cfg_attr is rare, and cfg can't increase length while let Some(attr) = queue.pop_front() { if attr.path().is_ident("cfg") { - if let Some(cfg) = self.errors.ok(attr.parse_args::()) { + if let Some(cfg) = self.errors.ok(Cfg::parse_meta(&attr.meta)) { if !self.eval_cfg(cfg) { return None; } continue; } } else if attr.path().is_ident("cfg_attr") { - if let Some(cfg_attr) = self.errors.ok(attr.parse_args::()) { + if let Some(cfg_attr) = self.errors.ok(CfgAttr::parse_meta(&attr.meta)) { if self.eval_cfg(cfg_attr.to_cfg()) { // push onto queue since cfg_attr(, cfg_attr(, )) is valid for meta in cfg_attr.attrs { - queue.push_front(Attribute { + queue.push_front(syn::Attribute { pound_token: attr.pound_token, style: attr.style, bracket_token: attr.bracket_token, @@ -88,6 +89,42 @@ impl State

{ } Some(Output::new(attrs)) } + fn process_qself_and_path( + &mut self, + qself: Option, + path: syn::Path, + ) -> Option<(Output, P>, Output)> { + let qself = if let Some(syn::QSelf { + lt_token, + ty, + position, + as_token, + gt_token, + }) = qself + { + ty.process(self)?.map(|ty| { + Some(syn::QSelf { + lt_token, + ty, + position, + as_token, + gt_token, + }) + }) + } else { + Output::new(None) + }; + let syn::Path { + leading_colon, + segments, + } = path; + // path segments don't get removed + let path = segments.process(self)?.map(|segments| syn::Path { + leading_colon, + segments, + }); + Some((qself, path)) + } } trait PhaseDispatch { @@ -259,7 +296,7 @@ impl Process

for syn::Item { } } -impl Process

for Vec { +impl Process

for Vec { fn process(self, state: &mut State

) -> Option> { state.eval_cfgs(self) } @@ -275,6 +312,10 @@ trait ProcessVecElement { const REMOVE_ELEMENTS: bool; } +impl ProcessVecElement for syn::Arm { + const REMOVE_ELEMENTS: bool = true; +} + impl ProcessVecElement for syn::Stmt { const REMOVE_ELEMENTS: bool = true; } @@ -317,34 +358,102 @@ trait ProcessOption { const REMOVE_VALUE: bool; } +impl ProcessOption for syn::Abi { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::Block { + const REMOVE_VALUE: bool = true; +} + impl ProcessOption for syn::WhereClause { const REMOVE_VALUE: bool = true; } +impl ProcessOption for syn::Expr { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::Type { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for Box { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::AngleBracketedGenericArguments { + const REMOVE_VALUE: bool = true; +} + impl ProcessOption for syn::ImplRestriction { const REMOVE_VALUE: bool = false; } +impl ProcessOption for syn::BoundLifetimes { + const REMOVE_VALUE: bool = false; +} + impl ProcessOption for (Token![=], syn::Expr) { const REMOVE_VALUE: bool = true; } +impl ProcessOption for (Token![=], syn::Type) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![if], Box) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![else], Box) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![&], Option) { + const REMOVE_VALUE: bool = true; +} + impl ProcessOption for (Token![as], Ident) { const REMOVE_VALUE: bool = true; } +impl ProcessOption for (Ident, Token![:]) { + const REMOVE_VALUE: bool = true; +} + impl ProcessOption for (Option, syn::Path, Token![for]) { const REMOVE_VALUE: bool = false; } +impl ProcessOption for syn::BareVariadic { + const REMOVE_VALUE: bool = true; +} + impl ProcessOption for syn::Variadic { const REMOVE_VALUE: bool = true; } +impl ProcessOption for syn::LocalInit { + const REMOVE_VALUE: bool = false; +} + +impl ProcessOption for syn::Label { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::PatRest { + const REMOVE_VALUE: bool = true; +} + impl ProcessOption for (Box, Token![:]) { const REMOVE_VALUE: bool = false; } +impl ProcessOption for (Token![@], Box) { + const REMOVE_VALUE: bool = false; +} + impl ProcessOption for (syn::token::Brace, Vec) { const REMOVE_VALUE: bool = false; } @@ -400,6 +509,18 @@ impl ProcessPunctuatedElement for syn::Type { const REMOVE_ELEMENTS: bool = true; } +impl ProcessPunctuatedElement for syn::Expr { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::Pat { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::CapturedParam { + const REMOVE_ELEMENTS: bool = true; +} + impl ProcessPunctuatedElement for syn::GenericArgument { const REMOVE_ELEMENTS: bool = true; } @@ -424,10 +545,30 @@ impl ProcessPunctuatedElement for syn::FnArg { const REMOVE_ELEMENTS: bool = true; } +impl ProcessPunctuatedElement for syn::BareFnArg { + const REMOVE_ELEMENTS: bool = true; +} + impl ProcessPunctuatedElement for syn::TypeParamBound { const REMOVE_ELEMENTS: bool = true; } +impl ProcessPunctuatedElement for syn::FieldValue { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::Field { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::FieldPat { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::UseTree { + const REMOVE_ELEMENTS: bool = true; +} + impl, U: Process

, P: Phase> Process

for (T, U) { fn process(self, state: &mut State

) -> Option> { let (t, u) = self; @@ -461,15 +602,14 @@ macro_rules! process_no_op { }; } -process_no_op!(syn::Visibility); -process_no_op!(syn::Lifetime); -process_no_op!(syn::Abi); -process_no_op!(syn::StaticMutability); +process_no_op!(Token![Self]); +process_no_op!(Token![abstract]); process_no_op!(Token![as]); process_no_op!(Token![async]); process_no_op!(Token![auto]); process_no_op!(Token![await]); process_no_op!(Token![become]); +process_no_op!(Token![box]); process_no_op!(Token![break]); process_no_op!(Token![const]); process_no_op!(Token![continue]); @@ -480,6 +620,7 @@ process_no_op!(Token![dyn]); process_no_op!(Token![else]); process_no_op!(Token![enum]); process_no_op!(Token![extern]); +process_no_op!(Token![final]); process_no_op!(Token![fn]); process_no_op!(Token![for]); process_no_op!(Token![if]); @@ -492,10 +633,12 @@ process_no_op!(Token![match]); process_no_op!(Token![mod]); process_no_op!(Token![move]); process_no_op!(Token![mut]); +process_no_op!(Token![override]); +process_no_op!(Token![priv]); process_no_op!(Token![pub]); +process_no_op!(Token![raw]); process_no_op!(Token![ref]); process_no_op!(Token![return]); -process_no_op!(Token![Self]); process_no_op!(Token![self]); process_no_op!(Token![static]); process_no_op!(Token![struct]); @@ -503,72 +646,88 @@ process_no_op!(Token![super]); process_no_op!(Token![trait]); process_no_op!(Token![try]); process_no_op!(Token![type]); +process_no_op!(Token![typeof]); process_no_op!(Token![union]); process_no_op!(Token![unsafe]); process_no_op!(Token![unsized]); process_no_op!(Token![use]); +process_no_op!(Token![virtual]); process_no_op!(Token![where]); process_no_op!(Token![while]); process_no_op!(Token![yield]); + +process_no_op!(Token![!]); +process_no_op!(Token![!=]); +process_no_op!(Token![#]); +process_no_op!(Token![$]); +process_no_op!(Token![%]); +process_no_op!(Token![%=]); process_no_op!(Token![&]); process_no_op!(Token![&&]); process_no_op!(Token![&=]); -process_no_op!(Token![@]); -process_no_op!(Token![^]); -process_no_op!(Token![^=]); -process_no_op!(Token![:]); +process_no_op!(Token![*]); +process_no_op!(Token![*=]); +process_no_op!(Token![+]); +process_no_op!(Token![+=]); process_no_op!(Token![,]); -process_no_op!(Token![$]); +process_no_op!(Token![-]); +process_no_op!(Token![-=]); +process_no_op!(Token![->]); process_no_op!(Token![.]); process_no_op!(Token![..]); process_no_op!(Token![...]); process_no_op!(Token![..=]); +process_no_op!(Token![/]); +process_no_op!(Token![/=]); +process_no_op!(Token![:]); +process_no_op!(Token![::]); +process_no_op!(Token![;]); +process_no_op!(Token![<]); +process_no_op!(Token![<-]); +process_no_op!(Token![<<]); +process_no_op!(Token![<<=]); +process_no_op!(Token![<=]); process_no_op!(Token![=]); process_no_op!(Token![==]); process_no_op!(Token![=>]); -process_no_op!(Token![>=]); process_no_op!(Token![>]); -process_no_op!(Token![<-]); -process_no_op!(Token![<=]); -process_no_op!(Token![<]); -process_no_op!(Token![-]); -process_no_op!(Token![-=]); -process_no_op!(Token![!=]); -process_no_op!(Token![!]); +process_no_op!(Token![>=]); +process_no_op!(Token![>>]); +process_no_op!(Token![>>=]); +process_no_op!(Token![?]); +process_no_op!(Token![@]); +process_no_op!(Token![^]); +process_no_op!(Token![^=]); +process_no_op!(Token![_]); process_no_op!(Token![|]); process_no_op!(Token![|=]); process_no_op!(Token![||]); -process_no_op!(Token![::]); -process_no_op!(Token![%]); -process_no_op!(Token![%=]); -process_no_op!(Token![+]); -process_no_op!(Token![+=]); -process_no_op!(Token![#]); -process_no_op!(Token![?]); -process_no_op!(Token![->]); -process_no_op!(Token![;]); -process_no_op!(Token![<<]); -process_no_op!(Token![<<=]); -process_no_op!(Token![>>]); -process_no_op!(Token![>>=]); -process_no_op!(Token![/]); -process_no_op!(Token![/=]); -process_no_op!(Token![*]); -process_no_op!(Token![*=]); process_no_op!(Token![~]); -process_no_op!(Token![_]); + process_no_op!(syn::token::Brace); process_no_op!(syn::token::Bracket); process_no_op!(syn::token::Paren); +process_no_op!(syn::token::Group); + process_no_op!(Ident); -process_no_op!(syn::UnOp); -process_no_op!(syn::Label); +process_no_op!(syn::Index); +process_no_op!(syn::Lifetime); +process_no_op!(syn::LitBool); +process_no_op!(syn::LitByte); +process_no_op!(syn::LitByteStr); +process_no_op!(syn::LitChar); +process_no_op!(syn::LitCStr); +process_no_op!(syn::LitFloat); +process_no_op!(syn::LitInt); +process_no_op!(syn::LitStr); +process_no_op!(proc_macro2::TokenStream); +process_no_op!(proc_macro2::Literal); macro_rules! process_struct { - ($path:path { + ($ty:path { $($field:ident,)* }) => { - impl Process

for $path { + impl Process

for $ty { fn process(self, state: &mut State

) -> Option> { let Self { $($field,)* @@ -580,21 +739,104 @@ macro_rules! process_struct { } } }; + ($ty:path { + $($fields_before:ident,)* + #[qself] + $qself:ident, + $path:ident, + $($fields_after:ident,)* + }) => { + impl Process

for $ty { + fn process(self, state: &mut State

) -> Option> { + let Self { + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + } = self; + $(let $fields_before = $fields_before.process(state)?;)* + let ($qself, $path) = state.process_qself_and_path($qself, $path)?; + $(let $fields_after = $fields_after.process(state)?;)* + Some(( + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + ).call(|( + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + )| Self { + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + })) + } + } + }; } process_struct! { - syn::Generics { - lt_token, - params, - gt_token, - where_clause, + syn::Abi { + extern_token, + name, } } process_struct! { - syn::WhereClause { - where_token, - predicates, + syn::AngleBracketedGenericArguments { + colon2_token, + lt_token, + args, + gt_token, + } +} + +process_struct! { + syn::Arm { + attrs, + pat, + guard, + fat_arrow_token, + body, + comma, + } +} + +process_struct! { + syn::AssocConst { + ident, + generics, + eq_token, + value, + } +} + +process_struct! { + syn::AssocType { + ident, + generics, + eq_token, + ty, + } +} + +process_struct! { + syn::BareFnArg { + attrs, + name, + ty, + } +} + +process_struct! { + syn::BareVariadic { + attrs, + name, + dots, + comma, } } @@ -606,321 +848,65 @@ process_struct! { } process_struct! { - syn::ItemConst { - attrs, - vis, - const_token, - ident, - generics, - colon_token, - ty, - eq_token, - expr, - semi_token, + syn::BoundLifetimes { + for_token, + lt_token, + lifetimes, + gt_token, } } process_struct! { - syn::ItemEnum { + syn::ConstParam { attrs, - vis, - enum_token, + const_token, + ident, + colon_token, + ty, + eq_token, + default, + } +} + +process_struct! { + syn::Constraint { ident, generics, + colon_token, + bounds, + } +} + +process_struct! { + syn::DataEnum { + enum_token, brace_token, variants, } } process_struct! { - syn::Variant { - attrs, - ident, - fields, - discriminant, - } -} - -process_struct! { - syn::ItemExternCrate { - attrs, - vis, - extern_token, - crate_token, - ident, - rename, - semi_token, - } -} - -process_struct! { - syn::ItemFn { - attrs, - vis, - sig, - block, - } -} - -process_struct! { - syn::Signature { - constness, - asyncness, - unsafety, - abi, - fn_token, - ident, - generics, - paren_token, - inputs, - variadic, - output, - } -} - -process_struct! { - syn::Variadic { - attrs, - pat, - dots, - comma, - } -} - -process_struct! { - syn::ItemForeignMod { - attrs, - unsafety, - abi, - brace_token, - items, - } -} - -process_struct! { - syn::ItemImpl { - attrs, - defaultness, - unsafety, - impl_token, - generics, - trait_, - self_ty, - brace_token, - items, - } -} - -process_struct! { - syn::ItemMacro { - attrs, - ident, - mac, - semi_token, - } -} - -process_struct! { - syn::ItemMod { - attrs, - vis, - unsafety, - mod_token, - ident, - content, - semi, - } -} - -process_struct! { - syn::ItemStatic { - attrs, - vis, - static_token, - mutability, - ident, - colon_token, - ty, - eq_token, - expr, - semi_token, - } -} - -process_struct! { - syn::ItemStruct { - attrs, - vis, + syn::DataStruct { struct_token, - ident, - generics, fields, semi_token, } } process_struct! { - syn::ItemTrait { - attrs, - vis, - unsafety, - auto_token, - restriction, - trait_token, - ident, - generics, - colon_token, - supertraits, - brace_token, - items, - } -} - -process_struct! { - syn::ItemTraitAlias { - attrs, - vis, - trait_token, - ident, - generics, - eq_token, - bounds, - semi_token, - } -} - -process_struct! { - syn::ItemType { - attrs, - vis, - type_token, - ident, - generics, - eq_token, - ty, - semi_token, - } -} - -process_struct! { - syn::ItemUnion { - attrs, - vis, + syn::DataUnion { union_token, - ident, - generics, fields, } } process_struct! { - syn::ItemUse { + syn::DeriveInput { attrs, vis, - use_token, - leading_colon, - tree, - semi_token, - } -} - -process_struct! { - syn::TypeArray { - bracket_token, - elem, - semi_token, - len, - } -} - -process_struct! { - syn::TypeBareFn { - lifetimes, - unsafety, - abi, - fn_token, - paren_token, - inputs, - variadic, - output, - } -} - -process_struct! { - syn::TypeGroup { - group_token, - elem, - } -} - -process_struct! { - syn::TypeImplTrait { - impl_token, - bounds, - } -} - -process_struct! { - syn::TypeInfer { - underscore_token, - } -} - -process_struct! { - syn::TypeMacro { - mac, - } -} - -process_struct! { - syn::TypeNever { - bang_token, - } -} - -process_struct! { - syn::TypeParen { - paren_token, - elem, - } -} - -process_struct! { - syn::TypePtr { - star_token, - const_token, - mutability, - elem, - } -} - -process_struct! { - syn::TypeReference { - and_token, - lifetime, - mutability, - elem, - } -} - -process_struct! { - syn::TypeSlice { - bracket_token, - elem, - } -} - -process_struct! { - syn::TypeTraitObject { - dyn_token, - bounds, - } -} - -process_struct! { - syn::TypeTuple { - paren_token, - elems, + ident, + generics, + data, } } @@ -1153,6 +1139,15 @@ process_struct! { } } +process_struct! { + syn::ExprPath { + attrs, + #[qself] + qself, + path, + } +} + process_struct! { syn::ExprRange { attrs, @@ -1162,6 +1157,16 @@ process_struct! { } } +process_struct! { + syn::ExprRawAddr { + attrs, + and_token, + raw, + mutability, + expr, + } +} + process_struct! { syn::ExprReference { attrs, @@ -1189,6 +1194,19 @@ process_struct! { } } +process_struct! { + syn::ExprStruct { + attrs, + #[qself] + qself, + path, + brace_token, + fields, + dot2_token, + rest, + } +} + process_struct! { syn::ExprTry { attrs, @@ -1247,6 +1265,348 @@ process_struct! { } } +process_struct! { + syn::Field { + attrs, + vis, + mutability, + ident, + colon_token, + ty, + } +} + +process_struct! { + syn::FieldPat { + attrs, + member, + colon_token, + pat, + } +} + +process_struct! { + syn::FieldValue { + attrs, + member, + colon_token, + expr, + } +} + +process_struct! { + syn::FieldsNamed { + brace_token, + named, + } +} + +process_struct! { + syn::FieldsUnnamed { + paren_token, + unnamed, + } +} + +process_struct! { + syn::ForeignItemFn { + attrs, + vis, + sig, + semi_token, + } +} + +process_struct! { + syn::ForeignItemMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::ForeignItemStatic { + attrs, + vis, + static_token, + mutability, + ident, + colon_token, + ty, + semi_token, + } +} + +process_struct! { + syn::ForeignItemType { + attrs, + vis, + type_token, + ident, + generics, + semi_token, + } +} + +process_struct! { + syn::Generics { + lt_token, + params, + gt_token, + where_clause, + } +} + +process_struct! { + syn::ImplItemConst { + attrs, + vis, + defaultness, + const_token, + ident, + generics, + colon_token, + ty, + eq_token, + expr, + semi_token, + } +} + +process_struct! { + syn::ImplItemFn { + attrs, + vis, + defaultness, + sig, + block, + } +} + +process_struct! { + syn::ImplItemMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::ImplItemType { + attrs, + vis, + defaultness, + type_token, + ident, + generics, + eq_token, + ty, + semi_token, + } +} + +process_struct! { + syn::ItemConst { + attrs, + vis, + const_token, + ident, + generics, + colon_token, + ty, + eq_token, + expr, + semi_token, + } +} + +process_struct! { + syn::ItemEnum { + attrs, + vis, + enum_token, + ident, + generics, + brace_token, + variants, + } +} + +process_struct! { + syn::ItemExternCrate { + attrs, + vis, + extern_token, + crate_token, + ident, + rename, + semi_token, + } +} + +process_struct! { + syn::ItemFn { + attrs, + vis, + sig, + block, + } +} + +process_struct! { + syn::ItemForeignMod { + attrs, + unsafety, + abi, + brace_token, + items, + } +} + +process_struct! { + syn::ItemImpl { + attrs, + defaultness, + unsafety, + impl_token, + generics, + trait_, + self_ty, + brace_token, + items, + } +} + +process_struct! { + syn::ItemMacro { + attrs, + ident, + mac, + semi_token, + } +} + +process_struct! { + syn::ItemMod { + attrs, + vis, + unsafety, + mod_token, + ident, + content, + semi, + } +} + +process_struct! { + syn::ItemStatic { + attrs, + vis, + static_token, + mutability, + ident, + colon_token, + ty, + eq_token, + expr, + semi_token, + } +} + +process_struct! { + syn::ItemStruct { + attrs, + vis, + struct_token, + ident, + generics, + fields, + semi_token, + } +} + +process_struct! { + syn::ItemTrait { + attrs, + vis, + unsafety, + auto_token, + restriction, + trait_token, + ident, + generics, + colon_token, + supertraits, + brace_token, + items, + } +} + +process_struct! { + syn::ItemTraitAlias { + attrs, + vis, + trait_token, + ident, + generics, + eq_token, + bounds, + semi_token, + } +} + +process_struct! { + syn::ItemType { + attrs, + vis, + type_token, + ident, + generics, + eq_token, + ty, + semi_token, + } +} + +process_struct! { + syn::ItemUnion { + attrs, + vis, + union_token, + ident, + generics, + fields, + } +} + +process_struct! { + syn::ItemUse { + attrs, + vis, + use_token, + leading_colon, + tree, + semi_token, + } +} + +process_struct! { + syn::Label { + name, + colon_token, + } +} + +process_struct! { + syn::LifetimeParam { + attrs, + lifetime, + colon_token, + bounds, + } +} + process_struct! { syn::Local { attrs, @@ -1257,14 +1617,6 @@ process_struct! { } } -process_struct! { - syn::StmtMacro { - attrs, - mac, - semi_token, - } -} - process_struct! { syn::LocalInit { eq_token, @@ -1273,6 +1625,136 @@ process_struct! { } } +process_struct! { + syn::Macro { + path, + bang_token, + delimiter, + tokens, + } +} + +process_struct! { + syn::MetaList { + path, + delimiter, + tokens, + } +} + +process_struct! { + syn::MetaNameValue { + path, + eq_token, + value, + } +} + +process_struct! { + syn::ParenthesizedGenericArguments { + paren_token, + inputs, + output, + } +} + +process_struct! { + syn::PatIdent { + attrs, + by_ref, + mutability, + ident, + subpat, + } +} + +process_struct! { + syn::PatOr { + attrs, + leading_vert, + cases, + } +} + +process_struct! { + syn::PatParen { + attrs, + paren_token, + pat, + } +} + +process_struct! { + syn::PatReference { + attrs, + and_token, + mutability, + pat, + } +} + +process_struct! { + syn::PatRest { + attrs, + dot2_token, + } +} + +process_struct! { + syn::PatSlice { + attrs, + bracket_token, + elems, + } +} + +process_struct! { + syn::PatStruct { + attrs, + #[qself] + qself, + path, + brace_token, + fields, + rest, + } +} + +process_struct! { + syn::PatTuple { + attrs, + paren_token, + elems, + } +} + +process_struct! { + syn::PatTupleStruct { + attrs, + #[qself] + qself, + path, + paren_token, + elems, + } +} + +process_struct! { + syn::PatType { + attrs, + pat, + colon_token, + ty, + } +} + +process_struct! { + syn::PatWild { + attrs, + underscore_token, + } +} + process_struct! { syn::Path { leading_colon, @@ -1288,81 +1770,14 @@ process_struct! { } process_struct! { - syn::AngleBracketedGenericArguments { - colon2_token, + syn::PreciseCapture { + use_token, lt_token, - args, + params, gt_token, } } -process_struct! { - syn::ParenthesizedGenericArguments { - paren_token, - inputs, - output, - } -} - -process_struct! { - syn::LifetimeParam { - attrs, - lifetime, - colon_token, - bounds, - } -} - -process_struct! { - syn::TypeParam { - attrs, - ident, - colon_token, - bounds, - eq_token, - default, - } -} - -process_struct! { - syn::ConstParam { - attrs, - const_token, - ident, - colon_token, - ty, - eq_token, - default, - } -} - -process_struct! { - syn::ExprPath { - attrs, - qself, - path, - } -} - -process_struct! { - syn::ExprStruct { - attrs, - qself, - path, - brace_token, - fields, - dot2_token, - rest, - } -} - -process_struct! { - syn::TypePath { - qself, - path, - } -} - process_struct! { syn::PredicateLifetime { lifetime, @@ -1381,58 +1796,302 @@ process_struct! { } process_struct! { - syn::FieldsNamed { - brace_token, - named, + syn::Receiver { + attrs, + reference, + mutability, + self_token, + colon_token, + ty, } } process_struct! { - syn::FieldsUnnamed { + syn::Signature { + constness, + asyncness, + unsafety, + abi, + fn_token, + ident, + generics, paren_token, - unnamed, + inputs, + variadic, + output, } } -impl Process

for syn::Macro { - fn process(self, state: &mut State

) -> Option> { - let Self { - path, - bang_token, - delimiter, - tokens, - } = self; - let path = path.process(state)?; - Some(path.map(|path| Self { - path, - bang_token, - delimiter, - tokens, - })) +process_struct! { + syn::StmtMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::TraitBound { + paren_token, + modifier, + lifetimes, + path, + } +} + +process_struct! { + syn::TraitItemConst { + attrs, + const_token, + ident, + generics, + colon_token, + ty, + default, + semi_token, + } +} + +process_struct! { + syn::TraitItemFn { + attrs, + sig, + default, + semi_token, + } +} + +process_struct! { + syn::TraitItemMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::TraitItemType { + attrs, + type_token, + ident, + generics, + colon_token, + bounds, + default, + semi_token, + } +} + +process_struct! { + syn::TypeArray { + bracket_token, + elem, + semi_token, + len, + } +} + +process_struct! { + syn::TypeBareFn { + lifetimes, + unsafety, + abi, + fn_token, + paren_token, + inputs, + variadic, + output, + } +} + +process_struct! { + syn::TypeGroup { + group_token, + elem, + } +} + +process_struct! { + syn::TypeImplTrait { + impl_token, + bounds, + } +} + +process_struct! { + syn::TypeInfer { + underscore_token, + } +} + +process_struct! { + syn::TypeMacro { + mac, + } +} + +process_struct! { + syn::TypeNever { + bang_token, + } +} + +process_struct! { + syn::TypeParam { + attrs, + ident, + colon_token, + bounds, + eq_token, + default, + } +} + +process_struct! { + syn::TypeParen { + paren_token, + elem, + } +} + +process_struct! { + syn::TypePath { + #[qself] + qself, + path, + } +} + +process_struct! { + syn::TypePtr { + star_token, + const_token, + mutability, + elem, + } +} + +process_struct! { + syn::TypeReference { + and_token, + lifetime, + mutability, + elem, + } +} + +process_struct! { + syn::TypeSlice { + bracket_token, + elem, + } +} + +process_struct! { + syn::TypeTraitObject { + dyn_token, + bounds, + } +} + +process_struct! { + syn::TypeTuple { + paren_token, + elems, + } +} + +process_struct! { + syn::UseGlob { + star_token, + } +} + +process_struct! { + syn::UseGroup { + brace_token, + items, + } +} + +process_struct! { + syn::UseName { + ident, + } +} + +process_struct! { + syn::UsePath { + ident, + colon2_token, + tree, + } +} + +process_struct! { + syn::UseRename { + ident, + as_token, + rename, + } +} + +process_struct! { + syn::Variadic { + attrs, + pat, + dots, + comma, + } +} + +process_struct! { + syn::Variant { + attrs, + ident, + fields, + discriminant, + } +} + +process_struct! { + syn::VisRestricted { + pub_token, + paren_token, + in_token, + path, + } +} + +process_struct! { + syn::WhereClause { + where_token, + predicates, } } macro_rules! process_enum { ($path:path { - $($variant:ident,)* + $($variant:ident$(($($field:ident),* $(,)?))?,)* }) => { impl Process

for $path { fn process(self, state: &mut State

) -> Option> { match self { - $(Self::$variant(v) => Some(v.process(state)?.map(Self::$variant)),)* + $(Self::$variant$(($($field),*))? => Some(($($($field.process(state)?,)*)?).call(|($($($field,)*)?)| Self::$variant$(($($field),*))?)),)* } } } }; ($path:path { - $($variant:ident,)* + $($variant:ident$(($($field:ident),* $(,)?))?,)* #[no_op] _, }) => { impl Process

for $path { fn process(self, state: &mut State

) -> Option> { + #![allow(unused_variables)] match self { - $(Self::$variant(v) => Some(v.process(state)?.map(Self::$variant)),)* + $(Self::$variant$(($($field),*))? => Some(($($($field.process(state)?,)*)?).call(|($($($field,)*)?)| Self::$variant$(($($field),*))?)),)* _ => Some(Output::new(self)), } } @@ -1441,66 +2100,154 @@ macro_rules! process_enum { } process_enum! { - syn::Type { - Array, - BareFn, - Group, - ImplTrait, - Infer, - Macro, - Never, - Paren, - Path, - Ptr, - Reference, - Slice, - TraitObject, - Tuple, + syn::AttrStyle { + Outer, + Inner(f0), + } +} + +process_enum! { + syn::BinOp { + Add(f0), + Sub(f0), + Mul(f0), + Div(f0), + Rem(f0), + And(f0), + Or(f0), + BitXor(f0), + BitAnd(f0), + BitOr(f0), + Shl(f0), + Shr(f0), + Eq(f0), + Lt(f0), + Le(f0), + Ne(f0), + Ge(f0), + Gt(f0), + AddAssign(f0), + SubAssign(f0), + MulAssign(f0), + DivAssign(f0), + RemAssign(f0), + BitXorAssign(f0), + BitAndAssign(f0), + BitOrAssign(f0), + ShlAssign(f0), + ShrAssign(f0), #[no_op] _, } } +process_enum! { + syn::CapturedParam { + Lifetime(f0), + Ident(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::Data { + Struct(f0), + Enum(f0), + Union(f0), + } +} + process_enum! { syn::Expr { - Array, - Assign, - Async, - Await, - Binary, - Block, - Break, - Call, - Cast, - Closure, - Const, - Continue, - Field, - ForLoop, - Group, - If, - Index, - Infer, - Let, - Lit, - Loop, - Macro, - Match, - MethodCall, - Paren, - Path, - Range, - Reference, - Repeat, - Return, - Struct, - Try, - TryBlock, - Tuple, - Unary, - Unsafe, - While, - Yield, + Array(f0), + Assign(f0), + Async(f0), + Await(f0), + Binary(f0), + Block(f0), + Break(f0), + Call(f0), + Cast(f0), + Closure(f0), + Const(f0), + Continue(f0), + Field(f0), + ForLoop(f0), + Group(f0), + If(f0), + Index(f0), + Infer(f0), + Let(f0), + Lit(f0), + Loop(f0), + Macro(f0), + Match(f0), + MethodCall(f0), + Paren(f0), + Path(f0), + Range(f0), + RawAddr(f0), + Reference(f0), + Repeat(f0), + Return(f0), + Struct(f0), + Try(f0), + TryBlock(f0), + Tuple(f0), + Unary(f0), + Unsafe(f0), + Verbatim(f0), + While(f0), + Yield(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::FieldMutability { + None, + #[no_op] + _, + } +} + +process_enum! { + syn::Fields { + Named(f0), + Unnamed(f0), + Unit, + } +} + +process_enum! { + syn::FnArg { + Receiver(f0), + Typed(f0), + } +} + +process_enum! { + syn::ForeignItem { + Fn(f0), + Static(f0), + Type(f0), + Macro(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::GenericArgument { + Lifetime(f0), + Type(f0), + Const(f0), + AssocType(f0), + AssocConst(f0), + Constraint(f0), #[no_op] _, } @@ -1508,81 +2255,177 @@ process_enum! { process_enum! { syn::GenericParam { - Lifetime, - Type, - Const, - } -} - -process_enum! { - syn::FnArg { - Receiver, - Typed, - } -} - -process_enum! { - syn::GenericArgument { - Lifetime, - Type, - Const, - AssocType, - AssocConst, - Constraint, - #[no_op] - _, - } -} - -process_enum! { - syn::WherePredicate { - Lifetime, - Type, - #[no_op] - _, - } -} - -process_enum! { - syn::Pat { - Const, - Ident, - Lit, - Macro, - Or, - Paren, - Path, - Range, - Reference, - Rest, - Slice, - Struct, - Tuple, - TupleStruct, - Type, - Wild, - #[no_op] - _, - } -} - -process_enum! { - syn::ForeignItem { - Fn, - Static, - Type, - Macro, - #[no_op] - _, + Lifetime(f0), + Type(f0), + Const(f0), } } process_enum! { syn::ImplItem { - Const, - Fn, - Type, - Macro, + Const(f0), + Fn(f0), + Type(f0), + Macro(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::ImplRestriction { + #[no_op] + _, + } +} + +process_enum! { + syn::Lit { + Str(f0), + ByteStr(f0), + CStr(f0), + Byte(f0), + Char(f0), + Int(f0), + Float(f0), + Bool(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::MacroDelimiter { + Paren(f0), + Brace(f0), + Bracket(f0), + } +} + +process_enum! { + syn::Member { + Named(f0), + Unnamed(f0), + } +} + +process_enum! { + syn::Meta { + Path(f0), + List(f0), + NameValue(f0), + } +} + +process_enum! { + syn::Pat { + Const(f0), + Ident(f0), + Lit(f0), + Macro(f0), + Or(f0), + Paren(f0), + Path(f0), + Range(f0), + Reference(f0), + Rest(f0), + Slice(f0), + Struct(f0), + Tuple(f0), + TupleStruct(f0), + Type(f0), + Verbatim(f0), + Wild(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::PathArguments { + None, + AngleBracketed(f0), + Parenthesized(f0), + } +} + +process_enum! { + syn::PointerMutability { + Const(f0), + Mut(f0), + } +} + +process_enum! { + syn::RangeLimits { + HalfOpen(f0), + Closed(f0), + } +} + +process_enum! { + syn::ReturnType { + Default, + Type(f0, f1), + } +} + +process_enum! { + syn::StaticMutability { + Mut(f0), + None, + #[no_op] + _, + } +} + +process_enum! { + syn::Stmt { + Local(f0), + Item(f0), + Expr(f0, f1), + Macro(f0), + } +} + +process_enum! { + syn::TraitBoundModifier { + None, + Maybe(f0), + } +} + +process_enum! { + syn::TraitItem { + Const(f0), + Fn(f0), + Type(f0), + Macro(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::Type { + Array(f0), + BareFn(f0), + Group(f0), + ImplTrait(f0), + Infer(f0), + Macro(f0), + Never(f0), + Paren(f0), + Path(f0), + Ptr(f0), + Reference(f0), + Slice(f0), + TraitObject(f0), + Tuple(f0), + Verbatim(f0), #[no_op] _, } @@ -1590,61 +2433,49 @@ process_enum! { process_enum! { syn::TypeParamBound { - Trait, - Lifetime, + Trait(f0), + Lifetime(f0), + PreciseCapture(f0), + Verbatim(f0), #[no_op] _, } } process_enum! { - syn::TraitItem { - Const, - Fn, - Type, - Macro, + syn::UnOp { + Deref(f0), + Not(f0), + Neg(f0), #[no_op] _, } } -impl Process

for syn::ReturnType { - fn process(self, state: &mut State

) -> Option> { - match self { - Self::Type(r_arrow, ty) => Some(ty.process(state)?.map(|ty| Self::Type(r_arrow, ty))), - Self::Default => Some(Output::new(Self::Default)), - } +process_enum! { + syn::UseTree { + Path(f0), + Name(f0), + Rename(f0), + Glob(f0), + Group(f0), } } -impl Process

for syn::Fields { - fn process(self, state: &mut State

) -> Option> { - match self { - Self::Named(v) => Some(v.process(state)?.map(Self::Named)), - Self::Unnamed(v) => Some(v.process(state)?.map(Self::Unnamed)), - Self::Unit => Some(Output::new(Self::Unit)), - } +process_enum! { + syn::Visibility { + Public(f0), + Restricted(f0), + Inherited, } } -impl Process

for syn::PathArguments { - fn process(self, state: &mut State

) -> Option> { - match self { - Self::None => Some(Output::new(Self::None)), - Self::AngleBracketed(v) => Some(v.process(state)?.map(Self::AngleBracketed)), - Self::Parenthesized(v) => Some(v.process(state)?.map(Self::Parenthesized)), - } - } -} - -impl Process

for syn::Stmt { - fn process(self, state: &mut State

) -> Option> { - match self { - Self::Local(v) => Some(v.process(state)?.map(Self::Local)), - Self::Item(v) => Some(v.process(state)?.map(Self::Item)), - Self::Expr(v, semi) => Some(v.process(state)?.map(|v| Self::Expr(v, semi))), - Self::Macro(v) => Some(v.process(state)?.map(Self::Macro)), - } +process_enum! { + syn::WherePredicate { + Lifetime(f0), + Type(f0), + #[no_op] + _, } } @@ -1673,12 +2504,6 @@ impl Process

for TopItem { } } -impl Process

for syn::ImplRestriction { - fn process(self, _state: &mut State

) -> Option> { - todo!("ImplRestriction is an uninhabited type as of writing, blocked on syn implementing impl restrictions") - } -} - pub(crate) fn process_cfgs(item: syn::Item, cfgs: Cfgs) -> syn::Result> { let mut state = State:: { cfgs, @@ -1692,11 +2517,7 @@ pub(crate) fn process_cfgs(item: syn::Item, cfgs: Cfgs) -> syn::Result syn::Result> { let mut state = State:: { - cfgs: Cfgs { - bracket: Default::default(), - cfgs_map: HashMap::new(), - cfgs_list: Vec::new(), - }, + cfgs: Cfgs::default(), errors: Errors::new(), _phantom: PhantomData, }; diff --git a/crates/fayalite-proc-macros/src/lib.rs b/crates/fayalite-proc-macros/src/lib.rs index b2aed0e..73dad09 100644 --- a/crates/fayalite-proc-macros/src/lib.rs +++ b/crates/fayalite-proc-macros/src/lib.rs @@ -27,12 +27,3 @@ pub fn hdl( Err(err) => err.into_compile_error().into(), } } - -#[doc(hidden)] -#[proc_macro] -pub fn __after_cfg_expansion(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - match fayalite_proc_macros_impl::after_cfg_expansion(input.into()) { - Ok(retval) => retval.into(), - Err(err) => err.into_compile_error().into(), - } -} diff --git a/crates/fayalite/build.rs b/crates/fayalite/build.rs index a32260c..c6680d5 100644 --- a/crates/fayalite/build.rs +++ b/crates/fayalite/build.rs @@ -6,6 +6,7 @@ use std::{env, fs, path::Path}; fn main() { println!("cargo::rustc-check-cfg=cfg(todo)"); println!("cargo::rustc-check-cfg=cfg(cfg_false_for_tests)"); + println!("cargo::rustc-check-cfg=cfg(cfg_true_for_tests)"); println!("cargo::rustc-cfg=cfg_true_for_tests"); let path = "visit_types.json"; println!("cargo::rerun-if-changed={path}"); diff --git a/crates/fayalite/src/lib.rs b/crates/fayalite/src/lib.rs index ea04841..5b5afb4 100644 --- a/crates/fayalite/src/lib.rs +++ b/crates/fayalite/src/lib.rs @@ -22,7 +22,7 @@ macro_rules! __cfg_expansion_helper { $cfg:ident($($expr:tt)*), $($unevaluated_cfgs:ident($($unevaluated_exprs:tt)*),)* ] - $after_evaluation:path {$($after_evaluation_args:tt)*} + #[$after_evaluation:path:($($after_evaluation_attr_args:tt)*)] {$($after_evaluation_args:tt)*} ) => { #[$cfg($($expr)*)] $crate::__cfg_expansion_helper! { @@ -33,7 +33,7 @@ macro_rules! __cfg_expansion_helper { [ $($unevaluated_cfgs($($unevaluated_exprs)*),)* ] - $after_evaluation {$($after_evaluation_args)*} + #[$after_evaluation:($($after_evaluation_attr_args)*)] {$($after_evaluation_args)*} } #[$cfg(not($($expr)*))] $crate::__cfg_expansion_helper! { @@ -44,7 +44,7 @@ macro_rules! __cfg_expansion_helper { [ $($unevaluated_cfgs($($unevaluated_exprs)*),)* ] - $after_evaluation {$($after_evaluation_args)*} + #[$after_evaluation:($($after_evaluation_attr_args)*)] {$($after_evaluation_args)*} } }; ( @@ -52,14 +52,12 @@ macro_rules! __cfg_expansion_helper { $($evaluated_cfgs:ident($($evaluated_exprs:tt)*) = $evaluated_results:ident,)* ] [] - $after_evaluation:path {$($after_evaluation_args:tt)*} + #[$after_evaluation:path:($($after_evaluation_attr_args:tt)*)] {$($after_evaluation_args:tt)*} ) => { - $after_evaluation! { - [ - $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* - ] - $($after_evaluation_args)* - } + #[$after_evaluation([ + $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* + ] $($after_evaluation_attr_args)*)] + $($after_evaluation_args)* }; } @@ -75,9 +73,6 @@ pub use fayalite_proc_macros::hdl_module; #[doc(inline)] pub use fayalite_proc_macros::hdl; -#[doc(hidden)] -pub use fayalite_proc_macros::__after_cfg_expansion; - /// struct used as a placeholder when applying defaults #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct __; diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index f303593..42cc528 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -4289,7 +4289,7 @@ circuit check_deduce_resets: } #[hdl_module(outline_generated)] -pub fn check_cfgs<#[cfg(cfg_false_for_tests)] A, #[cfg(cfg_true_for_tests)] B>( +pub fn check_cfgs<#[cfg(cfg_false_for_tests)] A: Type, #[cfg(cfg_true_for_tests)] B: Type>( #[cfg(cfg_false_for_tests)] a: A, #[cfg(cfg_true_for_tests)] b: B, ) { @@ -4313,52 +4313,34 @@ pub fn check_cfgs<#[cfg(cfg_false_for_tests)] A, #[cfg(cfg_true_for_tests)] B>( #[hdl] let o_a: A = m.output(a); connect(o_a, w.a.cast_bits_to(a)); - connect(w.a, i_a.cast_to_bits(UInt::new_static())); + connect_any(w.a, i_a.cast_to_bits()); } #[cfg(cfg_true_for_tests)] { #[hdl] - let o_a: B = m.output(b); + let o_b: B = m.output(b); connect(o_b, w.b.cast_bits_to(b)); - connect(w.b, i_b.cast_to_bits(UInt::new_static())); + connect_any(w.b, i_b.cast_to_bits()); } } #[test] fn test_cfgs() { let _n = SourceLocation::normalize_files_for_tests(); - let m = check_cfgs(UInt::<8>); + let m = check_cfgs(UInt[8]); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => - options: ExportOptions { - simplify_enums: None, - ..ExportOptions::default() - }, - "/test/check_deduce_resets.fir": r"FIRRTL version 3.2.0 -circuit check_deduce_resets: - type Ty0 = {clk: Clock, rst: Reset} - type Ty1 = {|A: Reset, B: AsyncReset, C: UInt<1>|} - module check_deduce_resets: @[module-XXXXXXXXXX.rs 1:1] - input cd: Ty0 @[module-XXXXXXXXXX.rs 2:1] - input u8_in: UInt<8> @[module-XXXXXXXXXX.rs 4:1] - output u8_out: UInt<8> @[module-XXXXXXXXXX.rs 6:1] - input enum_in: Ty1 @[module-XXXXXXXXXX.rs 8:1] - output enum_out: Ty1 @[module-XXXXXXXXXX.rs 9:1] - output reset_out: Reset @[module-XXXXXXXXXX.rs 10:1] - regreset my_reg: UInt<8>, cd.clk, cd.rst, UInt<8>(0h0) @[module-XXXXXXXXXX.rs 3:1] - connect my_reg, u8_in @[module-XXXXXXXXXX.rs 5:1] - connect u8_out, my_reg @[module-XXXXXXXXXX.rs 7:1] - connect reset_out, cd.rst @[module-XXXXXXXXXX.rs 11:1] - match enum_in: @[module-XXXXXXXXXX.rs 12:1] - A(_match_arm_value): - connect enum_out, {|A: Reset, B: AsyncReset, C: UInt<1>|}(A, cd.rst) @[module-XXXXXXXXXX.rs 13:1] - connect reset_out, _match_arm_value @[module-XXXXXXXXXX.rs 14:1] - B(_match_arm_value_1): - connect enum_out, {|A: Reset, B: AsyncReset, C: UInt<1>|}(B, _match_arm_value_1) @[module-XXXXXXXXXX.rs 15:1] - C(_match_arm_value_2): - connect enum_out, {|A: Reset, B: AsyncReset, C: UInt<1>|}(C, _match_arm_value_2) @[module-XXXXXXXXXX.rs 16:1] + "/test/check_cfgs.fir": r"FIRRTL version 3.2.0 +circuit check_cfgs: + type Ty0 = {b: UInt<8>} + module check_cfgs: @[module-XXXXXXXXXX.rs 1:1] + input i_b: UInt<8> @[module-XXXXXXXXXX.rs 2:1] + output o_b: UInt<8> @[module-XXXXXXXXXX.rs 4:1] + wire w: Ty0 @[module-XXXXXXXXXX.rs 3:1] + connect o_b, w.b @[module-XXXXXXXXXX.rs 5:1] + connect w.b, i_b @[module-XXXXXXXXXX.rs 6:1] ", }; }