From 26a709017873c47d2d7d81efb8d2159fd04fd928 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 6 Nov 2025 20:22:53 -0800 Subject: [PATCH 1/2] add ParsedVisibility --- .../src/hdl_type_common.rs | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs index f5b353e..3a0e5e9 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs @@ -4612,3 +4612,124 @@ impl MakeHdlTypeExpr for ParsedTypeTuple { }) } } + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) enum ParsedSimpleVisibility { + Public(Token![pub]), + PubCrate { + pub_token: Token![pub], + paren_token: Paren, + crate_token: Token![crate], + }, + Inherited, +} + +impl From for Visibility { + fn from(value: ParsedSimpleVisibility) -> Self { + match value { + ParsedSimpleVisibility::Public(v) => Visibility::Public(v), + ParsedSimpleVisibility::PubCrate { + pub_token, + paren_token, + crate_token, + } => Visibility::Restricted(syn::VisRestricted { + pub_token, + paren_token, + in_token: None, + path: Box::new(Ident::new("crate", crate_token.span).into()), + }), + ParsedSimpleVisibility::Inherited => Visibility::Inherited, + } + } +} + +impl PartialOrd for ParsedSimpleVisibility { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for ParsedSimpleVisibility { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.visibility_level().cmp(&other.visibility_level()) + } +} + +impl ParsedSimpleVisibility { + const VISIBILITY_LEVEL_INHERITED: u8 = 0; + const VISIBILITY_LEVEL_RESTRICTED: u8 = 1 + Self::VISIBILITY_LEVEL_INHERITED; + const VISIBILITY_LEVEL_PUB_CRATE: u8 = 1 + Self::VISIBILITY_LEVEL_RESTRICTED; + const VISIBILITY_LEVEL_PUB: u8 = 1 + Self::VISIBILITY_LEVEL_PUB_CRATE; + fn visibility_level(self) -> u8 { + match self { + Self::Public(_) => Self::VISIBILITY_LEVEL_PUB, + Self::PubCrate { .. } => Self::VISIBILITY_LEVEL_PUB_CRATE, + Self::Inherited => Self::VISIBILITY_LEVEL_INHERITED, + } + } + pub(crate) fn parse(vis: Visibility) -> Result { + match vis { + Visibility::Public(v) => Ok(Self::Public(v)), + Visibility::Restricted(syn::VisRestricted { + pub_token, + paren_token, + in_token: None, + path, + }) if path.is_ident("crate") => Ok(Self::PubCrate { + pub_token, + paren_token, + crate_token: Token![crate](path.get_ident().expect("just checked").span()), + }), + Visibility::Restricted(v) => Err(v), + Visibility::Inherited => Ok(Self::Inherited), + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) enum ParsedVisibility { + Simple(ParsedSimpleVisibility), + Restricted(syn::VisRestricted), +} + +impl From for Visibility { + fn from(value: ParsedVisibility) -> Self { + match value { + ParsedVisibility::Simple(v) => v.into(), + ParsedVisibility::Restricted(v) => Visibility::Restricted(v), + } + } +} + +impl PartialOrd for ParsedVisibility { + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (ParsedVisibility::Simple(l), ParsedVisibility::Simple(r)) => Some(l.cmp(r)), + (ParsedVisibility::Simple(l), ParsedVisibility::Restricted(_)) => Some( + l.visibility_level() + .cmp(&ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED), + ), + (ParsedVisibility::Restricted(_), ParsedVisibility::Simple(r)) => { + Some(ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED.cmp(&r.visibility_level())) + } + (ParsedVisibility::Restricted(l), ParsedVisibility::Restricted(r)) => { + (l == r).then_some(std::cmp::Ordering::Equal) + } + } + } +} + +impl ParsedVisibility { + #[allow(dead_code)] + pub(crate) fn parse(vis: Visibility) -> Self { + match ParsedSimpleVisibility::parse(vis) { + Ok(simple) => Self::Simple(simple), + Err(restricted) => Self::Restricted(restricted), + } + } + #[allow(dead_code)] + pub(crate) fn min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> { + self.partial_cmp(other) + .map(|ord| if ord.is_lt() { self } else { other }) + } +} -- 2.49.1 From fbc8ffa5aea6cc76d643880cd21a34993fb1ec4f Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 6 Nov 2025 20:23:16 -0800 Subject: [PATCH 2/2] fix private fields in #[hdl] pub struct --- .../src/hdl_bundle.rs | 11 ++----- crates/fayalite/src/bundle.rs | 25 ++++++---------- crates/fayalite/src/int/uint_in_range.rs | 2 -- crates/fayalite/tests/hdl_types.rs | 30 +++++++++++++++++++ 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs index e8dc51b..f952f42 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs @@ -224,7 +224,7 @@ impl Builder { .args .push_value(match get_field_state(field_index) { BuilderFieldState::Unfilled => parse_quote_spanned! {self.ident.span()=> - ::fayalite::bundle::Unfilled<#ty> + () }, BuilderFieldState::Generic => { let type_var = type_var_for_field_name(ident); @@ -383,7 +383,7 @@ impl ToTokens for Builder { fn default() -> Self { #ident { #phantom_field_name: ::fayalite::__std::marker::PhantomData, - #(#field_idents: ::fayalite::__std::default::Default::default(),)* + #(#field_idents: (),)* } } } @@ -395,7 +395,7 @@ impl ToTokens for Builder { let type_generics = self.generics.split_for_impl().1; quote_spanned! {self.ident.span()=> #[automatically_derived] - #[allow(non_camel_case_types, dead_code)] + #[allow(non_camel_case_types, dead_code, private_interfaces)] impl #filled_impl_generics ::fayalite::expr::ToExpr for #filled_ty #filled_where_clause { @@ -499,7 +499,6 @@ impl ToTokens for ParsedBundle { }; builder.to_tokens(tokens); let unfilled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Unfilled); - let filled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Filled); let mut mask_type_fields = FieldsNamed::from(fields.clone()); for Field { ty, .. } in &mut mask_type_fields.named { *ty = parse_quote_spanned! {span=> @@ -517,8 +516,6 @@ impl ToTokens for ParsedBundle { mask_type_builder.to_tokens(tokens); let unfilled_mask_type_builder_ty = mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled); - let filled_mask_type_builder_ty = - mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Filled); ItemStruct { attrs: vec![ common_derives(span), @@ -785,7 +782,6 @@ impl ToTokens for ParsedBundle { #where_clause { type Builder = #unfilled_mask_type_builder_ty; - type FilledBuilder = #filled_mask_type_builder_ty; fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> { ::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..]) } @@ -935,7 +931,6 @@ impl ToTokens for ParsedBundle { #where_clause { type Builder = #unfilled_builder_ty; - type FilledBuilder = #filled_builder_ty; fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> { ::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..]) } diff --git a/crates/fayalite/src/bundle.rs b/crates/fayalite/src/bundle.rs index a0de189..0edf192 100644 --- a/crates/fayalite/src/bundle.rs +++ b/crates/fayalite/src/bundle.rs @@ -271,7 +271,6 @@ impl Type for Bundle { pub trait BundleType: Type { type Builder: Default; - type FilledBuilder: ToExpr; fn fields(&self) -> Interned<[BundleField]>; } @@ -374,17 +373,8 @@ impl<'a> BundleSimValueToOpaque<'a> { #[derive(Default)] pub struct NoBuilder; -pub struct Unfilled(PhantomData); - -impl Default for Unfilled { - fn default() -> Self { - Self(PhantomData) - } -} - impl BundleType for Bundle { type Builder = NoBuilder; - type FilledBuilder = Expr; fn fields(&self) -> Interned<[BundleField]> { self.0.fields } @@ -420,15 +410,14 @@ macro_rules! impl_tuple_builder_fields { ) => { impl< $($head_type_var,)* - $cur_type_var: Type, $($tail_type_var,)* > TupleBuilder<( $($head_type_var,)* - Unfilled<$cur_type_var>, + (), $($tail_type_var,)* )> { - pub fn $cur_field(self, $cur_var: impl ToExpr) -> TupleBuilder<( + pub fn $cur_field<$cur_type_var: Type>(self, $cur_var: impl ToExpr) -> TupleBuilder<( $($head_type_var,)* Expr<$cur_type_var>, $($tail_type_var,)* @@ -452,6 +441,12 @@ macro_rules! impl_tuple_builder_fields { ($global:tt []) => {}; } +macro_rules! get_unit_ty { + ($($tt:tt)*) => { + () + }; +} + macro_rules! impl_tuples { ( [$({ @@ -545,8 +540,7 @@ macro_rules! impl_tuples { } } impl<$($T: Type,)*> BundleType for ($($T,)*) { - type Builder = TupleBuilder<($(Unfilled<$T>,)*)>; - type FilledBuilder = TupleBuilder<($(Expr<$T>,)*)>; + type Builder = TupleBuilder<($(get_unit_ty!($T),)*)>; fn fields(&self) -> Interned<[BundleField]> { let ($($var,)*) = self; [$(BundleField { name: stringify!($num).intern(), flipped: false, ty: $var.canonical() }),*].intern_slice() @@ -791,7 +785,6 @@ impl ToExpr for PhantomDataBuilder { impl BundleType for PhantomData { type Builder = PhantomDataBuilder; - type FilledBuilder = PhantomDataBuilder; fn fields(&self) -> Interned<[BundleField]> { Interned::default() } diff --git a/crates/fayalite/src/int/uint_in_range.rs b/crates/fayalite/src/int/uint_in_range.rs index 65d3092..4ed101e 100644 --- a/crates/fayalite/src/int/uint_in_range.rs +++ b/crates/fayalite/src/int/uint_in_range.rs @@ -96,7 +96,6 @@ impl Type for UIntInRangeMaskType { impl BundleType for UIntInRangeMaskType { type Builder = NoBuilder; - type FilledBuilder = Expr; fn fields(&self) -> Interned<[BundleField]> { let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES; @@ -400,7 +399,6 @@ macro_rules! define_uint_in_range_type { impl BundleType for $UIntInRangeType { type Builder = NoBuilder; - type FilledBuilder = Expr; fn fields(&self) -> Interned<[BundleField]> { let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES; diff --git a/crates/fayalite/tests/hdl_types.rs b/crates/fayalite/tests/hdl_types.rs index 148cb64..5030282 100644 --- a/crates/fayalite/tests/hdl_types.rs +++ b/crates/fayalite/tests/hdl_types.rs @@ -214,3 +214,33 @@ pub struct MyTypeWithPhantomConstParameter>, pub b: HdlOption>, } + +#[hdl(outline_generated)] +struct MyPrivateType {} + +#[hdl(outline_generated)] +pub(crate) struct MyPubCrateType {} + +#[hdl(outline_generated)] +pub struct MyTypeWithPrivateMembers { + a: MyPrivateType, + pub(crate) b: MyPubCrateType, + pub c: Bool, +} + +#[hdl(outline_generated)] +struct MyPrivateTypeWithArg { + v: T, +} + +#[hdl(outline_generated)] +pub(crate) struct MyPubCrateTypeWithArg { + v: T, +} + +#[hdl(outline_generated)] +pub struct MyTypeWithPrivateMembersWithArg { + a: MyPrivateTypeWithArg, + pub(crate) b: MyPubCrateTypeWithArg, + pub c: T, +} -- 2.49.1