forked from libre-chip/fayalite
fix #[hdl] to work with unusual identifier hygiene from macros
This commit is contained in:
parent
15a28aa7a7
commit
343805f80b
5 changed files with 202 additions and 112 deletions
|
@ -431,6 +431,7 @@ impl ToTokens for ParsedBundle {
|
|||
builder_ident,
|
||||
mask_type_builder_ident,
|
||||
} = self;
|
||||
let span = ident.span();
|
||||
let ItemOptions {
|
||||
outline_generated: _,
|
||||
target,
|
||||
|
@ -440,7 +441,7 @@ impl ToTokens for ParsedBundle {
|
|||
} = &options.body;
|
||||
let target = get_target(target, ident);
|
||||
let mut item_attrs = attrs.clone();
|
||||
item_attrs.push(common_derives(ident.span()));
|
||||
item_attrs.push(common_derives(span));
|
||||
ItemStruct {
|
||||
attrs: item_attrs,
|
||||
vis: vis.clone(),
|
||||
|
@ -462,19 +463,19 @@ impl ToTokens for ParsedBundle {
|
|||
.map(|ParsedField { ident, ty, .. }| {
|
||||
let ident = ident.as_ref().unwrap();
|
||||
let expr = ty.make_hdl_type_expr(context);
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: #expr,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
parse_quote_spanned! {ident.span()=>
|
||||
parse_quote_spanned! {span=>
|
||||
#target {
|
||||
#(#fields)*
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
let mut wrapped_in_const = WrappedInConst::new(tokens, ident.span());
|
||||
let mut wrapped_in_const = WrappedInConst::new(tokens, span);
|
||||
let tokens = wrapped_in_const.inner();
|
||||
let builder = Builder {
|
||||
vis: vis.clone(),
|
||||
|
@ -488,9 +489,8 @@ impl ToTokens for ParsedBundle {
|
|||
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 { ident, ty, .. } in &mut mask_type_fields.named {
|
||||
let ident = ident.as_ref().unwrap();
|
||||
*ty = parse_quote_spanned! {ident.span()=>
|
||||
for Field { ty, .. } in &mut mask_type_fields.named {
|
||||
*ty = parse_quote_spanned! {span=>
|
||||
<#ty as ::fayalite::ty::Type>::MaskType
|
||||
};
|
||||
}
|
||||
|
@ -509,8 +509,8 @@ impl ToTokens for ParsedBundle {
|
|||
mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Filled);
|
||||
ItemStruct {
|
||||
attrs: vec![
|
||||
common_derives(ident.span()),
|
||||
parse_quote_spanned! {ident.span()=>
|
||||
common_derives(span),
|
||||
parse_quote_spanned! {span=>
|
||||
#[allow(non_camel_case_types, dead_code)]
|
||||
},
|
||||
],
|
||||
|
@ -523,16 +523,15 @@ impl ToTokens for ParsedBundle {
|
|||
}
|
||||
.to_tokens(tokens);
|
||||
let mut mask_type_match_variant_fields = mask_type_fields;
|
||||
for Field { ident, ty, .. } in &mut mask_type_match_variant_fields.named {
|
||||
let ident = ident.as_ref().unwrap();
|
||||
*ty = parse_quote_spanned! {ident.span()=>
|
||||
for Field { ty, .. } in &mut mask_type_match_variant_fields.named {
|
||||
*ty = parse_quote_spanned! {span=>
|
||||
::fayalite::expr::Expr<#ty>
|
||||
};
|
||||
}
|
||||
ItemStruct {
|
||||
attrs: vec![
|
||||
common_derives(ident.span()),
|
||||
parse_quote_spanned! {ident.span()=>
|
||||
common_derives(span),
|
||||
parse_quote_spanned! {span=>
|
||||
#[allow(non_camel_case_types, dead_code)]
|
||||
},
|
||||
],
|
||||
|
@ -545,16 +544,15 @@ impl ToTokens for ParsedBundle {
|
|||
}
|
||||
.to_tokens(tokens);
|
||||
let mut match_variant_fields = FieldsNamed::from(fields.clone());
|
||||
for Field { ident, ty, .. } in &mut match_variant_fields.named {
|
||||
let ident = ident.as_ref().unwrap();
|
||||
*ty = parse_quote_spanned! {ident.span()=>
|
||||
for Field { ty, .. } in &mut match_variant_fields.named {
|
||||
*ty = parse_quote_spanned! {span=>
|
||||
::fayalite::expr::Expr<#ty>
|
||||
};
|
||||
}
|
||||
ItemStruct {
|
||||
attrs: vec![
|
||||
common_derives(ident.span()),
|
||||
parse_quote_spanned! {ident.span()=>
|
||||
common_derives(span),
|
||||
parse_quote_spanned! {span=>
|
||||
#[allow(non_camel_case_types, dead_code)]
|
||||
},
|
||||
],
|
||||
|
@ -566,17 +564,20 @@ impl ToTokens for ParsedBundle {
|
|||
semi_token: None,
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
let this_token = Ident::new("__this", span);
|
||||
let fields_token = Ident::new("__fields", span);
|
||||
let self_token = Token;
|
||||
let match_variant_body_fields = Vec::from_iter(fields.named().into_iter().map(|field| {
|
||||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
let ident_str = ident.to_string();
|
||||
quote_spanned! {ident.span()=>
|
||||
#ident: ::fayalite::expr::Expr::field(__this, #ident_str),
|
||||
quote_spanned! {span=>
|
||||
#ident: ::fayalite::expr::Expr::field(#this_token, #ident_str),
|
||||
}
|
||||
}));
|
||||
let mask_type_body_fields = Vec::from_iter(fields.named().into_iter().map(|field| {
|
||||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
quote_spanned! {ident.span()=>
|
||||
#ident: ::fayalite::ty::Type::mask_type(&self.#ident),
|
||||
quote_spanned! {span=>
|
||||
#ident: ::fayalite::ty::Type::mask_type(&#self_token.#ident),
|
||||
}
|
||||
}));
|
||||
let from_canonical_body_fields =
|
||||
|
@ -585,13 +586,13 @@ impl ToTokens for ParsedBundle {
|
|||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
let ident_str = ident.to_string();
|
||||
let flipped = flip.is_some();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: {
|
||||
let ::fayalite::bundle::BundleField {
|
||||
name: __name,
|
||||
flipped: __flipped,
|
||||
ty: __ty,
|
||||
} = __fields[#index];
|
||||
} = #fields_token[#index];
|
||||
::fayalite::__std::assert_eq!(&*__name, #ident_str);
|
||||
::fayalite::__std::assert_eq!(__flipped, #flipped);
|
||||
::fayalite::ty::Type::from_canonical(__ty)
|
||||
|
@ -604,17 +605,17 @@ impl ToTokens for ParsedBundle {
|
|||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
let ident_str = ident.to_string();
|
||||
let flipped = flip.is_some();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
::fayalite::bundle::BundleField {
|
||||
name: ::fayalite::intern::Intern::intern(#ident_str),
|
||||
flipped: #flipped,
|
||||
ty: ::fayalite::ty::Type::canonical(&self.#ident),
|
||||
ty: ::fayalite::ty::Type::canonical(&#self_token.#ident),
|
||||
},
|
||||
}
|
||||
},
|
||||
));
|
||||
let fields_len = fields.named().into_iter().len();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::ty::Type for #mask_type_ident #type_generics
|
||||
#where_clause
|
||||
|
@ -630,7 +631,7 @@ impl ToTokens for ParsedBundle {
|
|||
<Self as ::fayalite::ty::Type>::MatchVariantAndInactiveScope,
|
||||
>;
|
||||
fn match_variants(
|
||||
__this: ::fayalite::expr::Expr<Self>,
|
||||
#this_token: ::fayalite::expr::Expr<Self>,
|
||||
__source_location: ::fayalite::source_location::SourceLocation,
|
||||
) -> <Self as ::fayalite::ty::Type>::MatchVariantsIter {
|
||||
let __retval = #mask_type_match_variant_ident {
|
||||
|
@ -638,19 +639,19 @@ impl ToTokens for ParsedBundle {
|
|||
};
|
||||
::fayalite::__std::iter::once(::fayalite::ty::MatchVariantWithoutScope(__retval))
|
||||
}
|
||||
fn mask_type(&self) -> <Self as ::fayalite::ty::Type>::MaskType {
|
||||
*self
|
||||
fn mask_type(&#self_token) -> <Self as ::fayalite::ty::Type>::MaskType {
|
||||
*#self_token
|
||||
}
|
||||
fn canonical(&self) -> ::fayalite::ty::CanonicalType {
|
||||
::fayalite::ty::Type::canonical(&::fayalite::bundle::Bundle::new(::fayalite::bundle::BundleType::fields(self)))
|
||||
fn canonical(&#self_token) -> ::fayalite::ty::CanonicalType {
|
||||
::fayalite::ty::Type::canonical(&::fayalite::bundle::Bundle::new(::fayalite::bundle::BundleType::fields(#self_token)))
|
||||
}
|
||||
#[track_caller]
|
||||
fn from_canonical(__canonical_type: ::fayalite::ty::CanonicalType) -> Self {
|
||||
let ::fayalite::ty::CanonicalType::Bundle(__bundle) = __canonical_type else {
|
||||
::fayalite::__std::panic!("expected bundle");
|
||||
};
|
||||
let __fields = ::fayalite::bundle::BundleType::fields(&__bundle);
|
||||
::fayalite::__std::assert_eq!(__fields.len(), #fields_len, "bundle has wrong number of fields");
|
||||
let #fields_token = ::fayalite::bundle::BundleType::fields(&__bundle);
|
||||
::fayalite::__std::assert_eq!(#fields_token.len(), #fields_len, "bundle has wrong number of fields");
|
||||
Self {
|
||||
#(#from_canonical_body_fields)*
|
||||
}
|
||||
|
@ -665,7 +666,7 @@ impl ToTokens for ParsedBundle {
|
|||
{
|
||||
type Builder = #unfilled_mask_type_builder_ty;
|
||||
type FilledBuilder = #filled_mask_type_builder_ty;
|
||||
fn fields(&self) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
||||
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
||||
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
|
||||
}
|
||||
}
|
||||
|
@ -680,8 +681,8 @@ impl ToTokens for ParsedBundle {
|
|||
impl #impl_generics ::fayalite::ty::TypeWithDeref for #mask_type_ident #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn expr_deref(__this: &::fayalite::expr::Expr<Self>) -> &<Self as ::fayalite::ty::Type>::MatchVariant {
|
||||
let __this = *__this;
|
||||
fn expr_deref(#this_token: &::fayalite::expr::Expr<Self>) -> &<Self as ::fayalite::ty::Type>::MatchVariant {
|
||||
let #this_token = *#this_token;
|
||||
let __retval = #mask_type_match_variant_ident {
|
||||
#(#match_variant_body_fields)*
|
||||
};
|
||||
|
@ -703,7 +704,7 @@ impl ToTokens for ParsedBundle {
|
|||
<Self as ::fayalite::ty::Type>::MatchVariantAndInactiveScope,
|
||||
>;
|
||||
fn match_variants(
|
||||
__this: ::fayalite::expr::Expr<Self>,
|
||||
#this_token: ::fayalite::expr::Expr<Self>,
|
||||
__source_location: ::fayalite::source_location::SourceLocation,
|
||||
) -> <Self as ::fayalite::ty::Type>::MatchVariantsIter {
|
||||
let __retval = #match_variant_ident {
|
||||
|
@ -711,21 +712,21 @@ impl ToTokens for ParsedBundle {
|
|||
};
|
||||
::fayalite::__std::iter::once(::fayalite::ty::MatchVariantWithoutScope(__retval))
|
||||
}
|
||||
fn mask_type(&self) -> <Self as ::fayalite::ty::Type>::MaskType {
|
||||
fn mask_type(&#self_token) -> <Self as ::fayalite::ty::Type>::MaskType {
|
||||
#mask_type_ident {
|
||||
#(#mask_type_body_fields)*
|
||||
}
|
||||
}
|
||||
fn canonical(&self) -> ::fayalite::ty::CanonicalType {
|
||||
::fayalite::ty::Type::canonical(&::fayalite::bundle::Bundle::new(::fayalite::bundle::BundleType::fields(self)))
|
||||
fn canonical(&#self_token) -> ::fayalite::ty::CanonicalType {
|
||||
::fayalite::ty::Type::canonical(&::fayalite::bundle::Bundle::new(::fayalite::bundle::BundleType::fields(#self_token)))
|
||||
}
|
||||
#[track_caller]
|
||||
fn from_canonical(__canonical_type: ::fayalite::ty::CanonicalType) -> Self {
|
||||
let ::fayalite::ty::CanonicalType::Bundle(__bundle) = __canonical_type else {
|
||||
::fayalite::__std::panic!("expected bundle");
|
||||
};
|
||||
let __fields = ::fayalite::bundle::BundleType::fields(&__bundle);
|
||||
::fayalite::__std::assert_eq!(__fields.len(), #fields_len, "bundle has wrong number of fields");
|
||||
let #fields_token = ::fayalite::bundle::BundleType::fields(&__bundle);
|
||||
::fayalite::__std::assert_eq!(#fields_token.len(), #fields_len, "bundle has wrong number of fields");
|
||||
Self {
|
||||
#(#from_canonical_body_fields)*
|
||||
}
|
||||
|
@ -740,7 +741,7 @@ impl ToTokens for ParsedBundle {
|
|||
{
|
||||
type Builder = #unfilled_builder_ty;
|
||||
type FilledBuilder = #filled_builder_ty;
|
||||
fn fields(&self) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
||||
fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> {
|
||||
::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..])
|
||||
}
|
||||
}
|
||||
|
@ -755,8 +756,8 @@ impl ToTokens for ParsedBundle {
|
|||
impl #impl_generics ::fayalite::ty::TypeWithDeref for #target #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn expr_deref(__this: &::fayalite::expr::Expr<Self>) -> &<Self as ::fayalite::ty::Type>::MatchVariant {
|
||||
let __this = *__this;
|
||||
fn expr_deref(#this_token: &::fayalite::expr::Expr<Self>) -> &<Self as ::fayalite::ty::Type>::MatchVariant {
|
||||
let #this_token = *#this_token;
|
||||
let __retval = #match_variant_ident {
|
||||
#(#match_variant_body_fields)*
|
||||
};
|
||||
|
@ -772,7 +773,7 @@ impl ToTokens for ParsedBundle {
|
|||
let static_type_body_fields = Vec::from_iter(fields.named().into_iter().map(|field| {
|
||||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
let ty = field.ty();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: <#ty as ::fayalite::ty::StaticType>::TYPE,
|
||||
}
|
||||
}));
|
||||
|
@ -780,28 +781,26 @@ impl ToTokens for ParsedBundle {
|
|||
Vec::from_iter(fields.named().into_iter().map(|field| {
|
||||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
let ty = field.ty();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: <#ty as ::fayalite::ty::StaticType>::MASK_TYPE,
|
||||
}
|
||||
}));
|
||||
let type_properties = format_ident!("__type_properties", span = ident.span());
|
||||
let type_properties = format_ident!("__type_properties", span = span);
|
||||
let type_properties_fields = Vec::from_iter(fields.named().into_iter().zip(field_flips).map(|(field, field_flip)| {
|
||||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
let flipped = field_flip.is_some();
|
||||
let ty = field.ty();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
let #type_properties = #type_properties.field(#flipped, <#ty as ::fayalite::ty::StaticType>::TYPE_PROPERTIES);
|
||||
}
|
||||
}));
|
||||
let type_properties_mask_fields = Vec::from_iter(fields.named().into_iter().zip(field_flips).map(|(field, field_flip)| {
|
||||
let ident: &Ident = field.ident().as_ref().unwrap();
|
||||
let flipped = field_flip.is_some();
|
||||
let ty = field.ty();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
let #type_properties = #type_properties.field(#flipped, <#ty as ::fayalite::ty::StaticType>::MASK_TYPE_PROPERTIES);
|
||||
}
|
||||
}));
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #static_impl_generics ::fayalite::ty::StaticType for #mask_type_ident #static_type_generics
|
||||
#static_where_clause
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue