fix #[hdl] to work with unusual identifier hygiene from macros
This commit is contained in:
parent
15a28aa7a7
commit
343805f80b
|
@ -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![self](span);
|
||||
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
|
||||
|
|
|
@ -204,6 +204,7 @@ impl ToTokens for ParsedEnum {
|
|||
variants,
|
||||
match_variant_ident,
|
||||
} = self;
|
||||
let span = ident.span();
|
||||
let ItemOptions {
|
||||
outline_generated: _,
|
||||
target,
|
||||
|
@ -213,8 +214,8 @@ impl ToTokens for ParsedEnum {
|
|||
} = &options.body;
|
||||
let target = get_target(target, ident);
|
||||
let mut struct_attrs = attrs.clone();
|
||||
struct_attrs.push(common_derives(ident.span()));
|
||||
struct_attrs.push(parse_quote_spanned! {ident.span()=>
|
||||
struct_attrs.push(common_derives(span));
|
||||
struct_attrs.push(parse_quote_spanned! {span=>
|
||||
#[allow(non_snake_case)]
|
||||
});
|
||||
let struct_fields = Punctuated::from_iter(variants.pairs().map_pair_value_ref(
|
||||
|
@ -238,8 +239,8 @@ impl ToTokens for ParsedEnum {
|
|||
colon_token = Token![:](paren_token.span.open());
|
||||
ty.clone().into()
|
||||
} else {
|
||||
colon_token = Token![:](ident.span());
|
||||
parse_quote_spanned! {ident.span()=>
|
||||
colon_token = Token![:](span);
|
||||
parse_quote_spanned! {span=>
|
||||
()
|
||||
}
|
||||
};
|
||||
|
@ -282,30 +283,30 @@ impl ToTokens for ParsedEnum {
|
|||
}) = field
|
||||
{
|
||||
let expr = ty.make_hdl_type_expr(context);
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: #expr,
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: (),
|
||||
}
|
||||
}
|
||||
})
|
||||
.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 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 mut enum_attrs = attrs.clone();
|
||||
enum_attrs.push(parse_quote_spanned! {ident.span()=>
|
||||
enum_attrs.push(parse_quote_spanned! {span=>
|
||||
#[allow(dead_code)]
|
||||
});
|
||||
ItemEnum {
|
||||
|
@ -354,7 +355,7 @@ impl ToTokens for ParsedEnum {
|
|||
.to_tokens(tokens);
|
||||
}
|
||||
let mut enum_attrs = attrs.clone();
|
||||
enum_attrs.push(parse_quote_spanned! {ident.span()=>
|
||||
enum_attrs.push(parse_quote_spanned! {span=>
|
||||
#[allow(dead_code, non_camel_case_types)]
|
||||
});
|
||||
ItemEnum {
|
||||
|
@ -389,7 +390,7 @@ impl ToTokens for ParsedEnum {
|
|||
mutability: FieldMutability::None,
|
||||
ident: None,
|
||||
colon_token: None,
|
||||
ty: parse_quote_spanned! {ident.span()=>
|
||||
ty: parse_quote_spanned! {span=>
|
||||
::fayalite::expr::Expr<#ty>
|
||||
},
|
||||
},
|
||||
|
@ -403,21 +404,22 @@ impl ToTokens for ParsedEnum {
|
|||
)),
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
let self_token = Token![self](span);
|
||||
for (index, ParsedVariant { ident, field, .. }) in variants.iter().enumerate() {
|
||||
if let Some(ParsedVariantField { ty, .. }) = field {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #impl_generics #target #type_generics
|
||||
#where_clause
|
||||
{
|
||||
#[allow(non_snake_case, dead_code)]
|
||||
#vis fn #ident<__V: ::fayalite::expr::ToExpr<Type = #ty>>(
|
||||
self,
|
||||
#self_token,
|
||||
v: __V,
|
||||
) -> ::fayalite::expr::Expr<Self> {
|
||||
::fayalite::expr::ToExpr::to_expr(
|
||||
&::fayalite::expr::ops::EnumLiteral::new_by_index(
|
||||
self,
|
||||
#self_token,
|
||||
#index,
|
||||
::fayalite::__std::option::Option::Some(
|
||||
::fayalite::expr::Expr::canonical(
|
||||
|
@ -430,16 +432,16 @@ impl ToTokens for ParsedEnum {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #impl_generics #target #type_generics
|
||||
#where_clause
|
||||
{
|
||||
#[allow(non_snake_case, dead_code)]
|
||||
#vis fn #ident(self) -> ::fayalite::expr::Expr<Self> {
|
||||
#vis fn #ident(#self_token) -> ::fayalite::expr::Expr<Self> {
|
||||
::fayalite::expr::ToExpr::to_expr(
|
||||
&::fayalite::expr::ops::EnumLiteral::new_by_index(
|
||||
self,
|
||||
#self_token,
|
||||
#index,
|
||||
::fayalite::__std::option::Option::None,
|
||||
),
|
||||
|
@ -450,46 +452,48 @@ impl ToTokens for ParsedEnum {
|
|||
}
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
let variants_token = Ident::new("variants", span);
|
||||
let from_canonical_body_fields = Vec::from_iter(variants.iter().enumerate().map(
|
||||
|(index, ParsedVariant { ident, field, .. })| {
|
||||
let ident_str = ident.to_string();
|
||||
let val = if field.is_some() {
|
||||
let missing_value_msg = format!("expected variant {ident} to have a field");
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
::fayalite::ty::Type::from_canonical(ty.expect(#missing_value_msg))
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
::fayalite::__std::assert!(ty.is_none());
|
||||
}
|
||||
};
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: {
|
||||
let ::fayalite::enum_::EnumVariant {
|
||||
name,
|
||||
ty,
|
||||
} = variants[#index];
|
||||
} = #variants_token[#index];
|
||||
::fayalite::__std::assert_eq!(&*name, #ident_str);
|
||||
#val
|
||||
},
|
||||
}
|
||||
},
|
||||
));
|
||||
let variant_access_token = Ident::new("variant_access", span);
|
||||
let match_active_scope_match_arms = Vec::from_iter(variants.iter().enumerate().map(
|
||||
|(index, ParsedVariant { ident, field, .. })| {
|
||||
if field.is_some() {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#index => #match_variant_ident::#ident(
|
||||
::fayalite::expr::ToExpr::to_expr(
|
||||
&::fayalite::expr::ops::VariantAccess::new_by_index(
|
||||
variant_access.base(),
|
||||
variant_access.variant_index(),
|
||||
#variant_access_token.base(),
|
||||
#variant_access_token.variant_index(),
|
||||
),
|
||||
),
|
||||
),
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#index => #match_variant_ident::#ident,
|
||||
}
|
||||
}
|
||||
|
@ -507,16 +511,16 @@ impl ToTokens for ParsedEnum {
|
|||
match field {
|
||||
Some(ParsedVariantField { options, .. }) => {
|
||||
let FieldOptions {} = options.body;
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
::fayalite::enum_::EnumVariant {
|
||||
name: ::fayalite::intern::Intern::intern(#ident_str),
|
||||
ty: ::fayalite::__std::option::Option::Some(
|
||||
::fayalite::ty::Type::canonical(&self.#ident),
|
||||
::fayalite::ty::Type::canonical(&#self_token.#ident),
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
None => quote_spanned! {ident.span()=>
|
||||
None => quote_spanned! {span=>
|
||||
::fayalite::enum_::EnumVariant {
|
||||
name: ::fayalite::intern::Intern::intern(#ident_str),
|
||||
ty: ::fayalite::__std::option::Option::None,
|
||||
|
@ -526,7 +530,7 @@ impl ToTokens for ParsedEnum {
|
|||
},
|
||||
));
|
||||
let variants_len = variants.len();
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::ty::Type for #target #type_generics
|
||||
#where_clause
|
||||
|
@ -544,11 +548,11 @@ impl ToTokens for ParsedEnum {
|
|||
) -> <Self as ::fayalite::ty::Type>::MatchVariantsIter {
|
||||
::fayalite::module::enum_match_variants_helper(this, source_location)
|
||||
}
|
||||
fn mask_type(&self) -> <Self as ::fayalite::ty::Type>::MaskType {
|
||||
fn mask_type(&#self_token) -> <Self as ::fayalite::ty::Type>::MaskType {
|
||||
::fayalite::int::Bool
|
||||
}
|
||||
fn canonical(&self) -> ::fayalite::ty::CanonicalType {
|
||||
::fayalite::ty::CanonicalType::Enum(::fayalite::enum_::Enum::new(::fayalite::enum_::EnumType::variants(self)))
|
||||
fn canonical(&#self_token) -> ::fayalite::ty::CanonicalType {
|
||||
::fayalite::ty::CanonicalType::Enum(::fayalite::enum_::Enum::new(::fayalite::enum_::EnumType::variants(#self_token)))
|
||||
}
|
||||
#[track_caller]
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -556,8 +560,8 @@ impl ToTokens for ParsedEnum {
|
|||
let ::fayalite::ty::CanonicalType::Enum(enum_) = canonical_type else {
|
||||
::fayalite::__std::panic!("expected enum");
|
||||
};
|
||||
let variants = ::fayalite::enum_::EnumType::variants(&enum_);
|
||||
::fayalite::__std::assert_eq!(variants.len(), #variants_len, "enum has wrong number of variants");
|
||||
let #variants_token = ::fayalite::enum_::EnumType::variants(&enum_);
|
||||
::fayalite::__std::assert_eq!(#variants_token.len(), #variants_len, "enum has wrong number of variants");
|
||||
Self {
|
||||
#(#from_canonical_body_fields)*
|
||||
}
|
||||
|
@ -573,16 +577,16 @@ impl ToTokens for ParsedEnum {
|
|||
fn match_activate_scope(
|
||||
v: <Self as ::fayalite::ty::Type>::MatchVariantAndInactiveScope,
|
||||
) -> (<Self as ::fayalite::ty::Type>::MatchVariant, <Self as ::fayalite::ty::Type>::MatchActiveScope) {
|
||||
let (variant_access, scope) = v.activate();
|
||||
let (#variant_access_token, scope) = v.activate();
|
||||
(
|
||||
match variant_access.variant_index() {
|
||||
match #variant_access_token.variant_index() {
|
||||
#(#match_active_scope_match_arms)*
|
||||
#variants_len.. => ::fayalite::__std::panic!("invalid variant index"),
|
||||
},
|
||||
scope,
|
||||
)
|
||||
}
|
||||
fn variants(&self) -> ::fayalite::intern::Interned<[::fayalite::enum_::EnumVariant]> {
|
||||
fn variants(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::enum_::EnumVariant]> {
|
||||
::fayalite::intern::Intern::intern(&[
|
||||
#(#variants_body_variants)*
|
||||
][..])
|
||||
|
@ -597,34 +601,34 @@ impl ToTokens for ParsedEnum {
|
|||
let static_type_body_variants =
|
||||
Vec::from_iter(variants.iter().map(|ParsedVariant { ident, field, .. }| {
|
||||
if let Some(_) = field {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: ::fayalite::ty::StaticType::TYPE,
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#ident: (),
|
||||
}
|
||||
}
|
||||
}));
|
||||
let type_properties = format_ident!("__type_properties", span = ident.span());
|
||||
let type_properties = format_ident!("__type_properties", span = span);
|
||||
let type_properties_variants =
|
||||
Vec::from_iter(variants.iter().map(|ParsedVariant { ident, field, .. }| {
|
||||
Vec::from_iter(variants.iter().map(|ParsedVariant { field, .. }| {
|
||||
let variant = if let Some(ParsedVariantField { ty, .. }) = field {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
::fayalite::__std::option::Option::Some(
|
||||
<#ty as ::fayalite::ty::StaticType>::TYPE_PROPERTIES,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
::fayalite::__std::option::Option::None
|
||||
}
|
||||
};
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
let #type_properties = #type_properties.variant(#variant);
|
||||
}
|
||||
}));
|
||||
quote_spanned! {ident.span()=>
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #static_impl_generics ::fayalite::ty::StaticType
|
||||
for #target #static_type_generics
|
||||
|
|
|
@ -1896,6 +1896,7 @@ pub(crate) mod known_items {
|
|||
impl_known_item!(::fayalite::array::ArrayType);
|
||||
impl_known_item!(::fayalite::bundle::BundleType);
|
||||
impl_known_item!(::fayalite::enum_::EnumType);
|
||||
impl_known_item!(::fayalite::int::BoolOrIntType);
|
||||
impl_known_item!(::fayalite::int::DynSize);
|
||||
impl_known_item!(::fayalite::int::IntType);
|
||||
impl_known_item!(::fayalite::int::KnownSize);
|
||||
|
@ -2085,6 +2086,7 @@ macro_rules! impl_bounds {
|
|||
impl_bounds! {
|
||||
#[struct = ParsedBounds]
|
||||
pub(crate) enum ParsedBound {
|
||||
BoolOrIntType,
|
||||
BundleType,
|
||||
EnumType,
|
||||
IntType,
|
||||
|
@ -2098,6 +2100,7 @@ impl_bounds! {
|
|||
impl_bounds! {
|
||||
#[struct = ParsedTypeBounds]
|
||||
pub(crate) enum ParsedTypeBound {
|
||||
BoolOrIntType,
|
||||
BundleType,
|
||||
EnumType,
|
||||
IntType,
|
||||
|
@ -2109,6 +2112,7 @@ impl_bounds! {
|
|||
impl From<ParsedTypeBound> for ParsedBound {
|
||||
fn from(value: ParsedTypeBound) -> Self {
|
||||
match value {
|
||||
ParsedTypeBound::BoolOrIntType(v) => ParsedBound::BoolOrIntType(v),
|
||||
ParsedTypeBound::BundleType(v) => ParsedBound::BundleType(v),
|
||||
ParsedTypeBound::EnumType(v) => ParsedBound::EnumType(v),
|
||||
ParsedTypeBound::IntType(v) => ParsedBound::IntType(v),
|
||||
|
@ -2121,6 +2125,7 @@ impl From<ParsedTypeBound> for ParsedBound {
|
|||
impl From<ParsedTypeBounds> for ParsedBounds {
|
||||
fn from(value: ParsedTypeBounds) -> Self {
|
||||
let ParsedTypeBounds {
|
||||
BoolOrIntType,
|
||||
BundleType,
|
||||
EnumType,
|
||||
IntType,
|
||||
|
@ -2128,6 +2133,7 @@ impl From<ParsedTypeBounds> for ParsedBounds {
|
|||
Type,
|
||||
} = value;
|
||||
Self {
|
||||
BoolOrIntType,
|
||||
BundleType,
|
||||
EnumType,
|
||||
IntType,
|
||||
|
@ -2143,6 +2149,10 @@ impl ParsedTypeBound {
|
|||
fn implied_bounds(self) -> ParsedTypeBounds {
|
||||
let span = self.span();
|
||||
match self {
|
||||
Self::BoolOrIntType(v) => ParsedTypeBounds::from_iter([
|
||||
ParsedTypeBound::from(v),
|
||||
ParsedTypeBound::Type(known_items::Type(span)),
|
||||
]),
|
||||
Self::BundleType(v) => ParsedTypeBounds::from_iter([
|
||||
ParsedTypeBound::from(v),
|
||||
ParsedTypeBound::Type(known_items::Type(span)),
|
||||
|
@ -2153,6 +2163,7 @@ impl ParsedTypeBound {
|
|||
]),
|
||||
Self::IntType(v) => ParsedTypeBounds::from_iter([
|
||||
ParsedTypeBound::from(v),
|
||||
ParsedTypeBound::BoolOrIntType(known_items::BoolOrIntType(span)),
|
||||
ParsedTypeBound::Type(known_items::Type(span)),
|
||||
]),
|
||||
Self::StaticType(v) => ParsedTypeBounds::from_iter([
|
||||
|
@ -2185,6 +2196,7 @@ impl From<ParsedSizeTypeBounds> for ParsedBounds {
|
|||
fn from(value: ParsedSizeTypeBounds) -> Self {
|
||||
let ParsedSizeTypeBounds { KnownSize, Size } = value;
|
||||
Self {
|
||||
BoolOrIntType: None,
|
||||
BundleType: None,
|
||||
EnumType: None,
|
||||
IntType: None,
|
||||
|
@ -2260,6 +2272,7 @@ pub(crate) enum ParsedBoundCategory {
|
|||
impl ParsedBound {
|
||||
fn categorize(self) -> ParsedBoundCategory {
|
||||
match self {
|
||||
Self::BoolOrIntType(v) => ParsedBoundCategory::Type(ParsedTypeBound::BoolOrIntType(v)),
|
||||
Self::BundleType(v) => ParsedBoundCategory::Type(ParsedTypeBound::BundleType(v)),
|
||||
Self::EnumType(v) => ParsedBoundCategory::Type(ParsedTypeBound::EnumType(v)),
|
||||
Self::IntType(v) => ParsedBoundCategory::Type(ParsedTypeBound::IntType(v)),
|
||||
|
@ -2575,6 +2588,7 @@ impl ParsedGenerics {
|
|||
}
|
||||
})
|
||||
.collect();
|
||||
let param_token = Ident::new("__param", ident.span());
|
||||
for (param_count, (generics_accumulation_type, next_param)) in generics_accumulation_types
|
||||
.iter()
|
||||
.zip(&self.params)
|
||||
|
@ -2623,7 +2637,7 @@ impl ParsedGenerics {
|
|||
next_generics.split_for_impl();
|
||||
let next_turbofish = next_type_generics.as_turbofish();
|
||||
let mut param: Expr = parse_quote_spanned! {ident.span()=>
|
||||
__param
|
||||
#param_token
|
||||
};
|
||||
let mut generics = next_generics.clone();
|
||||
let mut index_type = param_ident.clone();
|
||||
|
@ -2638,7 +2652,7 @@ impl ParsedGenerics {
|
|||
is_const: false,
|
||||
});
|
||||
param = parse_quote_spanned! {ident.span()=>
|
||||
::fayalite::ty::TypeOrDefault::get(__param, || #default_expr)
|
||||
::fayalite::ty::TypeOrDefault::get(#param_token, || #default_expr)
|
||||
};
|
||||
let context = MakeHdlTypeExprContext {
|
||||
named_param_values: self_members[..param_count]
|
||||
|
@ -2703,7 +2717,7 @@ impl ParsedGenerics {
|
|||
{
|
||||
type Output = #next_target #next_type_generics;
|
||||
|
||||
fn index(&self, __param: #index_type) -> &Self::Output {
|
||||
fn index(&self, #param_token: #index_type) -> &Self::Output {
|
||||
::fayalite::intern::Interned::<_>::into_inner(
|
||||
::fayalite::intern::Intern::intern_sized(#output_expr),
|
||||
)
|
||||
|
@ -2724,7 +2738,7 @@ impl ParsedGenerics {
|
|||
.iter()
|
||||
.cloned()
|
||||
.chain([parse_quote_spanned! {ident.span()=>
|
||||
__param
|
||||
#param_token
|
||||
}])
|
||||
.collect(),
|
||||
is_const: false,
|
||||
|
@ -2763,7 +2777,7 @@ impl ParsedGenerics {
|
|||
{
|
||||
type Output = #next_target #next_target_args;
|
||||
|
||||
fn index(&self, __param: #param_ident) -> &Self::Output {
|
||||
fn index(&self, #param_token: #param_ident) -> &Self::Output {
|
||||
::fayalite::intern::Interned::<_>::into_inner(
|
||||
::fayalite::intern::Intern::intern_sized(#output_expr),
|
||||
)
|
||||
|
@ -2791,7 +2805,7 @@ impl ParsedGenerics {
|
|||
.iter()
|
||||
.cloned()
|
||||
.chain([parse_quote_spanned! {ident.span()=>
|
||||
__param
|
||||
#param_token
|
||||
}])
|
||||
.collect(),
|
||||
is_const: false,
|
||||
|
@ -2833,7 +2847,7 @@ impl ParsedGenerics {
|
|||
{
|
||||
type Output = #next_target #next_target_args;
|
||||
|
||||
fn index(&self, __param: __Param) -> &Self::Output {
|
||||
fn index(&self, #param_token: __Param) -> &Self::Output {
|
||||
::fayalite::intern::Interned::<_>::into_inner(
|
||||
::fayalite::intern::Intern::intern_sized(#output_expr),
|
||||
)
|
||||
|
@ -3145,16 +3159,21 @@ impl ParsedGenerics {
|
|||
.Type
|
||||
.get_or_insert_with(|| known_items::Type(bound.span()));
|
||||
match bound {
|
||||
ParsedTypeBound::BundleType(_)
|
||||
ParsedTypeBound::BoolOrIntType(_)
|
||||
| ParsedTypeBound::BundleType(_)
|
||||
| ParsedTypeBound::EnumType(_)
|
||||
| ParsedTypeBound::IntType(_) => {
|
||||
errors.error(bound, "bound on mask type not implemented");
|
||||
}
|
||||
ParsedTypeBound::StaticType(bound) => {
|
||||
if bounds.StaticType.is_none() {
|
||||
errors.error(bound, "StaticType bound on mask type without corresponding StaticType bound on original type is not implemented");
|
||||
errors.error(
|
||||
bound,
|
||||
"StaticType bound on mask type without corresponding \
|
||||
StaticType bound on original type is not implemented",
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
ParsedTypeBound::Type(_) => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,7 +210,9 @@ impl sealed::BaseTypeSealed for CanonicalType {}
|
|||
|
||||
impl BaseType for CanonicalType {}
|
||||
|
||||
pub trait TypeOrDefault<D: Type>: sealed::TypeOrDefaultSealed {
|
||||
pub trait TypeOrDefault<D: Type>:
|
||||
sealed::TypeOrDefaultSealed + Copy + Eq + Hash + fmt::Debug
|
||||
{
|
||||
type Type: Type;
|
||||
fn get<F: FnOnce() -> D>(self, default: F) -> Self::Type;
|
||||
}
|
||||
|
|
|
@ -29,3 +29,69 @@ pub enum E<T> {
|
|||
pub struct S2<T = ()> {
|
||||
pub v: E<T>,
|
||||
}
|
||||
|
||||
// check that #[hdl] properly handles hygiene
|
||||
macro_rules! types_in_macros {
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident, $D:ident, $E:ident, $F:ident) => {
|
||||
#[hdl]
|
||||
struct $F {}
|
||||
#[hdl]
|
||||
struct $A<$B, $C: Size, const $D: usize, $E = $F> {
|
||||
$a: $B,
|
||||
$b: UIntType<$C>,
|
||||
$c: SInt<$D>,
|
||||
$d: HdlOption<$E>,
|
||||
$e: $E,
|
||||
$f: $F,
|
||||
}
|
||||
#[allow(non_camel_case_types)]
|
||||
#[hdl]
|
||||
enum $B<$C: Size, const $D: usize, $E = $F> {
|
||||
$a($A<(), $C, $D, $E>),
|
||||
$b(UIntType<$C>),
|
||||
$c(SInt<$D>),
|
||||
$d,
|
||||
$e($E),
|
||||
$f($F),
|
||||
}
|
||||
};
|
||||
// ensure every identifier has different hygiene
|
||||
() => {
|
||||
types_in_macros!(a);
|
||||
};
|
||||
($a:ident) => {
|
||||
types_in_macros!($a, b);
|
||||
};
|
||||
($a:ident, $b:ident) => {
|
||||
types_in_macros!($a, $b, c);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident) => {
|
||||
types_in_macros!($a, $b, $c, d);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, e);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, $e, f);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, $e, $f, A);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, $e, $f, $A, B);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, C);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, $C, D);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident, $D:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, $C, $D, E);
|
||||
};
|
||||
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident, $D:ident, $E:ident) => {
|
||||
types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, $C, $D, $E, F);
|
||||
};
|
||||
}
|
||||
|
||||
types_in_macros!();
|
||||
|
|
Loading…
Reference in a new issue