diff --git a/Cargo.lock b/Cargo.lock index 23cdc34..2e50abc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -543,9 +543,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -647,9 +647,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.93" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 54de3a8..2cfa586 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.93", features = ["full", "fold", "visit", "extra-traits"] } +syn = { version = "2.0.66", 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 1b1b61f..d7f2752 100644 --- a/crates/fayalite-proc-macros-impl/src/lib.rs +++ b/crates/fayalite-proc-macros-impl/src/lib.rs @@ -66,7 +66,6 @@ mod kw { }; } - custom_keyword!(__evaluated_cfgs); custom_keyword!(all); custom_keyword!(any); custom_keyword!(cfg); @@ -1023,12 +1022,6 @@ 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 { @@ -1075,9 +1068,6 @@ impl CfgAttr { trailing_comma: None, } } - fn parse_meta(meta: &Meta) -> syn::Result { - syn::parse2(meta.to_token_stream()) - } } impl Parse for CfgAttr { @@ -1115,16 +1105,6 @@ 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) { @@ -1145,11 +1125,10 @@ 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) => { @@ -1205,44 +1184,7 @@ impl ToTokens for Cfgs<()> { } } -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()); - }; +fn handle_top_level_attr(item: Item) -> syn::Result { match item { Item::Enum(item) => hdl_enum::hdl_enum(item), Item::Struct(item) => hdl_bundle::hdl_bundle(item), @@ -1255,10 +1197,39 @@ fn hdl_main( } } +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 { - hdl_main(kw::hdl_module::default(), attr, item) + let kw = kw::hdl_module::default(); + generate_cfg_expansion_tokens(quote! { #[#kw(#attr)] #item }) } pub fn hdl_attr(attr: TokenStream, item: TokenStream) -> syn::Result { - hdl_main(kw::hdl::default(), attr, item) + 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, + ) } diff --git a/crates/fayalite-proc-macros-impl/src/process_cfg.rs b/crates/fayalite-proc-macros-impl/src/process_cfg.rs index 5cff08f..06193cc 100644 --- a/crates/fayalite-proc-macros-impl/src/process_cfg.rs +++ b/crates/fayalite-proc-macros-impl/src/process_cfg.rs @@ -2,11 +2,13 @@ // See Notices.txt for copyright information use crate::{Cfg, CfgAttr, Cfgs, Errors}; -use proc_macro2::Ident; -use std::{collections::VecDeque, marker::PhantomData}; +use std::{ + collections::{HashMap, VecDeque}, + marker::PhantomData, +}; use syn::{ punctuated::{Pair, Punctuated}, - Token, + Attribute, Ident, Token, }; struct State { @@ -55,26 +57,23 @@ 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(Cfg::parse_meta(&attr.meta)) { + if let Some(cfg) = self.errors.ok(attr.parse_args::()) { if !self.eval_cfg(cfg) { return None; } continue; } } else if attr.path().is_ident("cfg_attr") { - if let Some(cfg_attr) = self.errors.ok(CfgAttr::parse_meta(&attr.meta)) { + if let Some(cfg_attr) = self.errors.ok(attr.parse_args::()) { 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(syn::Attribute { + queue.push_front(Attribute { pound_token: attr.pound_token, style: attr.style, bracket_token: attr.bracket_token, @@ -89,42 +88,6 @@ 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 { @@ -296,7 +259,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) } @@ -312,10 +275,6 @@ 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; } @@ -358,102 +317,34 @@ 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; } @@ -509,18 +400,6 @@ 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; } @@ -545,30 +424,10 @@ 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; @@ -602,14 +461,15 @@ macro_rules! process_no_op { }; } -process_no_op!(Token![Self]); -process_no_op!(Token![abstract]); +process_no_op!(syn::Visibility); +process_no_op!(syn::Lifetime); +process_no_op!(syn::Abi); +process_no_op!(syn::StaticMutability); 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]); @@ -620,7 +480,6 @@ 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]); @@ -633,12 +492,10 @@ 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]); @@ -646,88 +503,72 @@ 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::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); +process_no_op!(syn::UnOp); +process_no_op!(syn::Label); macro_rules! process_struct { - ($ty:path { + ($path:path { $($field:ident,)* }) => { - impl Process

for $ty { + impl Process

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

) -> Option> { let Self { $($field,)* @@ -739,104 +580,21 @@ 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::Abi { - extern_token, - name, - } -} - -process_struct! { - syn::AngleBracketedGenericArguments { - colon2_token, + syn::Generics { lt_token, - args, + params, gt_token, + where_clause, } } 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, + syn::WhereClause { + where_token, + predicates, } } @@ -848,65 +606,321 @@ process_struct! { } process_struct! { - syn::BoundLifetimes { - for_token, - lt_token, - lifetimes, - gt_token, - } -} - -process_struct! { - syn::ConstParam { + syn::ItemConst { attrs, + vis, const_token, - ident, - colon_token, - ty, - eq_token, - default, - } -} - -process_struct! { - syn::Constraint { ident, generics, colon_token, - bounds, + ty, + eq_token, + expr, + semi_token, } } process_struct! { - syn::DataEnum { + syn::ItemEnum { + attrs, + vis, enum_token, + ident, + generics, brace_token, variants, } } process_struct! { - syn::DataStruct { + 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, struct_token, + ident, + generics, fields, semi_token, } } process_struct! { - syn::DataUnion { + 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::DeriveInput { + syn::ItemUse { attrs, vis, - ident, - generics, - data, + 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, } } @@ -1139,15 +1153,6 @@ process_struct! { } } -process_struct! { - syn::ExprPath { - attrs, - #[qself] - qself, - path, - } -} - process_struct! { syn::ExprRange { attrs, @@ -1157,16 +1162,6 @@ process_struct! { } } -process_struct! { - syn::ExprRawAddr { - attrs, - and_token, - raw, - mutability, - expr, - } -} - process_struct! { syn::ExprReference { attrs, @@ -1194,19 +1189,6 @@ process_struct! { } } -process_struct! { - syn::ExprStruct { - attrs, - #[qself] - qself, - path, - brace_token, - fields, - dot2_token, - rest, - } -} - process_struct! { syn::ExprTry { attrs, @@ -1265,348 +1247,6 @@ 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, @@ -1617,6 +1257,14 @@ process_struct! { } } +process_struct! { + syn::StmtMacro { + attrs, + mac, + semi_token, + } +} + process_struct! { syn::LocalInit { eq_token, @@ -1625,136 +1273,6 @@ 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, @@ -1770,14 +1288,81 @@ process_struct! { } process_struct! { - syn::PreciseCapture { - use_token, + syn::AngleBracketedGenericArguments { + colon2_token, lt_token, - params, + args, 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, @@ -1796,302 +1381,58 @@ process_struct! { } process_struct! { - syn::Receiver { - attrs, - reference, - mutability, - self_token, - colon_token, - ty, - } -} - -process_struct! { - syn::Signature { - constness, - asyncness, - unsafety, - abi, - fn_token, - ident, - generics, - paren_token, - inputs, - variadic, - output, - } -} - -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 { + syn::FieldsNamed { brace_token, - items, + named, } } 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, + syn::FieldsUnnamed { paren_token, - in_token, - path, + unnamed, } } -process_struct! { - syn::WhereClause { - where_token, - predicates, +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, + })) } } macro_rules! process_enum { ($path:path { - $($variant:ident$(($($field:ident),* $(,)?))?,)* + $($variant:ident,)* }) => { impl Process

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

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

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

) -> Option> { - #![allow(unused_variables)] match self { - $(Self::$variant$(($($field),*))? => Some(($($($field.process(state)?,)*)?).call(|($($($field,)*)?)| Self::$variant$(($($field),*))?)),)* + $(Self::$variant(v) => Some(v.process(state)?.map(Self::$variant)),)* _ => Some(Output::new(self)), } } @@ -2100,154 +1441,66 @@ macro_rules! process_enum { } process_enum! { - 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), + syn::Type { + Array, + BareFn, + Group, + ImplTrait, + Infer, + Macro, + Never, + Paren, + Path, + Ptr, + Reference, + Slice, + TraitObject, + Tuple, #[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(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), + 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, #[no_op] _, } @@ -2255,177 +1508,81 @@ process_enum! { process_enum! { syn::GenericParam { - Lifetime(f0), - Type(f0), - Const(f0), + Lifetime, + Type, + Const, } } process_enum! { - syn::ImplItem { - Const(f0), - Fn(f0), - Type(f0), - Macro(f0), - Verbatim(f0), + syn::FnArg { + Receiver, + Typed, + } +} + +process_enum! { + syn::GenericArgument { + Lifetime, + Type, + Const, + AssocType, + AssocConst, + Constraint, #[no_op] _, } } process_enum! { - syn::ImplRestriction { + syn::WherePredicate { + Lifetime, + Type, #[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), + Const, + Ident, + Lit, + Macro, + Or, + Paren, + Path, + Range, + Reference, + Rest, + Slice, + Struct, + Tuple, + TupleStruct, + Type, + Wild, #[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, + syn::ForeignItem { + Fn, + Static, + Type, + Macro, #[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), + syn::ImplItem { + Const, + Fn, + Type, + Macro, #[no_op] _, } @@ -2433,49 +1590,61 @@ process_enum! { process_enum! { syn::TypeParamBound { - Trait(f0), - Lifetime(f0), - PreciseCapture(f0), - Verbatim(f0), + Trait, + Lifetime, #[no_op] _, } } process_enum! { - syn::UnOp { - Deref(f0), - Not(f0), - Neg(f0), + syn::TraitItem { + Const, + Fn, + Type, + Macro, #[no_op] _, } } -process_enum! { - syn::UseTree { - Path(f0), - Name(f0), - Rename(f0), - Glob(f0), - Group(f0), +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::Visibility { - Public(f0), - Restricted(f0), - Inherited, +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::WherePredicate { - Lifetime(f0), - Type(f0), - #[no_op] - _, +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)), + } } } @@ -2504,6 +1673,12 @@ 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, @@ -2517,7 +1692,11 @@ pub(crate) fn process_cfgs(item: syn::Item, cfgs: Cfgs) -> syn::Result syn::Result> { let mut state = State:: { - cfgs: Cfgs::default(), + cfgs: Cfgs { + bracket: Default::default(), + cfgs_map: HashMap::new(), + cfgs_list: Vec::new(), + }, errors: Errors::new(), _phantom: PhantomData, }; diff --git a/crates/fayalite-proc-macros/src/lib.rs b/crates/fayalite-proc-macros/src/lib.rs index 73dad09..b2aed0e 100644 --- a/crates/fayalite-proc-macros/src/lib.rs +++ b/crates/fayalite-proc-macros/src/lib.rs @@ -27,3 +27,12 @@ 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 c6680d5..a32260c 100644 --- a/crates/fayalite/build.rs +++ b/crates/fayalite/build.rs @@ -6,7 +6,6 @@ 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 5b5afb4..ea04841 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_attr_args:tt)*)] {$($after_evaluation_args:tt)*} + $after_evaluation:path {$($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_attr_args)*)] {$($after_evaluation_args)*} + $after_evaluation {$($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_attr_args)*)] {$($after_evaluation_args)*} + $after_evaluation {$($after_evaluation_args)*} } }; ( @@ -52,12 +52,14 @@ macro_rules! __cfg_expansion_helper { $($evaluated_cfgs:ident($($evaluated_exprs:tt)*) = $evaluated_results:ident,)* ] [] - #[$after_evaluation:path:($($after_evaluation_attr_args:tt)*)] {$($after_evaluation_args:tt)*} + $after_evaluation:path {$($after_evaluation_args:tt)*} ) => { - #[$after_evaluation([ - $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* - ] $($after_evaluation_attr_args)*)] - $($after_evaluation_args)* + $after_evaluation! { + [ + $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* + ] + $($after_evaluation_args)* + } }; } @@ -73,6 +75,9 @@ 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 42cc528..f303593 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: Type, #[cfg(cfg_true_for_tests)] B: Type>( +pub fn check_cfgs<#[cfg(cfg_false_for_tests)] A, #[cfg(cfg_true_for_tests)] B>( #[cfg(cfg_false_for_tests)] a: A, #[cfg(cfg_true_for_tests)] b: B, ) { @@ -4313,34 +4313,52 @@ pub fn check_cfgs<#[cfg(cfg_false_for_tests)] A: Type, #[cfg(cfg_true_for_tests) #[hdl] let o_a: A = m.output(a); connect(o_a, w.a.cast_bits_to(a)); - connect_any(w.a, i_a.cast_to_bits()); + connect(w.a, i_a.cast_to_bits(UInt::new_static())); } #[cfg(cfg_true_for_tests)] { #[hdl] - let o_b: B = m.output(b); + let o_a: B = m.output(b); connect(o_b, w.b.cast_bits_to(b)); - connect_any(w.b, i_b.cast_to_bits()); + connect(w.b, i_b.cast_to_bits(UInt::new_static())); } } #[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 => - "/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] + 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] ", }; }