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 | ||||
|  |  | |||
|  | @ -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); | ||||
|                     ty.clone().into() | ||||
|                 } else { | ||||
|                     colon_token = Token); | ||||
|                     parse_quote_spanned! {ident.span()=> | ||||
|                     colon_token = Token; | ||||
|                     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; | ||||
|         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…
	
	Add table
		Add a link
		
	
		Reference in a new issue