forked from libre-chip/fayalite
		
	add PhantomConstGet to the known Type bounds for #[hdl] struct/enum
This commit is contained in:
		
							parent
							
								
									4b24a88641
								
							
						
					
					
						commit
						0b82178740
					
				
					 4 changed files with 251 additions and 117 deletions
				
			
		|  | @ -3,111 +3,19 @@ | |||
| use crate::{ | ||||
|     Errors, HdlAttr, | ||||
|     hdl_type_common::{ | ||||
|         ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, TypesParser, | ||||
|         WrappedInConst, common_derives, get_target, known_items, | ||||
|         ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, | ||||
|         PhantomConstGetBound, TypesParser, WrappedInConst, common_derives, get_target, known_items, | ||||
|     }, | ||||
|     kw, | ||||
| }; | ||||
| use proc_macro2::TokenStream; | ||||
| use quote::{ToTokens, format_ident, quote_spanned}; | ||||
| use syn::{ | ||||
|     AngleBracketedGenericArguments, Attribute, Expr, Fields, GenericArgument, GenericParam, | ||||
|     Generics, Ident, ItemStruct, ItemType, Path, PathArguments, Token, TraitBound, | ||||
|     TraitBoundModifier, Type, TypeGroup, TypeParam, TypeParamBound, TypeParen, Visibility, | ||||
|     parse_quote_spanned, punctuated::Pair, token::Paren, | ||||
|     Attribute, Expr, Fields, GenericParam, Generics, Ident, ItemStruct, ItemType, Token, Type, | ||||
|     TypeGroup, TypeParam, TypeParen, Visibility, parse_quote_spanned, punctuated::Pair, | ||||
|     token::Paren, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub(crate) struct PhantomConstGetBound { | ||||
|     pub(crate) phantom_const_get: known_items::PhantomConstGet, | ||||
|     pub(crate) colon2_token: Option<Token![::]>, | ||||
|     pub(crate) lt_token: Token![<], | ||||
|     pub(crate) ty: Type, | ||||
|     pub(crate) comma_token: Option<Token![,]>, | ||||
|     pub(crate) gt_token: Token![>], | ||||
| } | ||||
| 
 | ||||
| impl From<PhantomConstGetBound> for Path { | ||||
|     fn from(value: PhantomConstGetBound) -> Self { | ||||
|         let PhantomConstGetBound { | ||||
|             phantom_const_get, | ||||
|             colon2_token, | ||||
|             lt_token, | ||||
|             ty, | ||||
|             comma_token, | ||||
|             gt_token, | ||||
|         } = value; | ||||
|         let mut path = phantom_const_get.path; | ||||
|         path.segments.last_mut().expect("known to exist").arguments = | ||||
|             PathArguments::AngleBracketed(AngleBracketedGenericArguments { | ||||
|                 colon2_token, | ||||
|                 lt_token, | ||||
|                 args: FromIterator::from_iter([Pair::new(GenericArgument::Type(ty), comma_token)]), | ||||
|                 gt_token, | ||||
|             }); | ||||
|         path | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<PhantomConstGetBound> for TraitBound { | ||||
|     fn from(value: PhantomConstGetBound) -> Self { | ||||
|         let path = Path::from(value); | ||||
|         TraitBound { | ||||
|             paren_token: None, | ||||
|             modifier: TraitBoundModifier::None, | ||||
|             lifetimes: None, | ||||
|             path, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<PhantomConstGetBound> for TypeParamBound { | ||||
|     fn from(value: PhantomConstGetBound) -> Self { | ||||
|         TraitBound::from(value).into() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl PhantomConstGetBound { | ||||
|     fn parse_opt(bound: TypeParamBound) -> Option<Self> { | ||||
|         let TypeParamBound::Trait(TraitBound { | ||||
|             paren_token: None, | ||||
|             modifier: TraitBoundModifier::None, | ||||
|             lifetimes: None, | ||||
|             path, | ||||
|         }) = bound | ||||
|         else { | ||||
|             return None; | ||||
|         }; | ||||
|         let Ok(( | ||||
|             phantom_const_get, | ||||
|             PathArguments::AngleBracketed(AngleBracketedGenericArguments { | ||||
|                 colon2_token, | ||||
|                 lt_token, | ||||
|                 args, | ||||
|                 gt_token, | ||||
|             }), | ||||
|         )) = known_items::PhantomConstGet::parse_path_with_arguments(path) | ||||
|         else { | ||||
|             return None; | ||||
|         }; | ||||
|         let mut args = args.into_pairs(); | ||||
|         let (GenericArgument::Type(ty), comma_token) = args.next()?.into_tuple() else { | ||||
|             return None; | ||||
|         }; | ||||
|         let None = args.next() else { | ||||
|             return None; | ||||
|         }; | ||||
|         Some(Self { | ||||
|             phantom_const_get, | ||||
|             colon2_token, | ||||
|             lt_token, | ||||
|             ty, | ||||
|             comma_token, | ||||
|             gt_token, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub(crate) struct PhantomConstAccessorTypeParam { | ||||
|     attrs: Vec<Attribute>, | ||||
|  | @ -162,7 +70,9 @@ impl PhantomConstAccessorTypeParam { | |||
|         let colon_token = colon_token.unwrap_or(Token)); | ||||
|         let mut bounds = bounds.into_pairs(); | ||||
|         let (bound, plus_token) = bounds.next()?.into_tuple(); | ||||
|         let phantom_const_get_bound = PhantomConstGetBound::parse_opt(bound)?; | ||||
|         let phantom_const_get_bound = PhantomConstGetBound::parse_type_param_bound(bound) | ||||
|             .ok()? | ||||
|             .ok()?; | ||||
|         let None = bounds.next() else { | ||||
|             return None; | ||||
|         }; | ||||
|  |  | |||
|  | @ -8,9 +8,9 @@ use syn::{ | |||
|     AngleBracketedGenericArguments, Attribute, Block, ConstParam, Expr, ExprBlock, ExprGroup, | ||||
|     ExprIndex, ExprParen, ExprPath, ExprTuple, Field, FieldMutability, Fields, FieldsNamed, | ||||
|     FieldsUnnamed, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index, ItemStruct, | ||||
|     Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, Turbofish, Type, | ||||
|     TypeGenerics, TypeGroup, TypeParam, TypeParen, TypePath, TypeTuple, Visibility, WhereClause, | ||||
|     WherePredicate, | ||||
|     Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, TraitBound, Turbofish, | ||||
|     Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath, TypeTuple, | ||||
|     Visibility, WhereClause, WherePredicate, | ||||
|     parse::{Parse, ParseStream}, | ||||
|     parse_quote, parse_quote_spanned, | ||||
|     punctuated::{Pair, Punctuated}, | ||||
|  | @ -2065,6 +2065,174 @@ pub(crate) mod known_items { | |||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub(crate) struct PhantomConstGetBound { | ||||
|     pub(crate) phantom_const_get: known_items::PhantomConstGet, | ||||
|     pub(crate) colon2_token: Option<Token![::]>, | ||||
|     pub(crate) lt_token: Token![<], | ||||
|     pub(crate) ty: Type, | ||||
|     pub(crate) comma_token: Option<Token![,]>, | ||||
|     pub(crate) gt_token: Token![>], | ||||
| } | ||||
| 
 | ||||
| impl PhantomConstGetBound { | ||||
|     pub(crate) fn parse_path_with_arguments(path: Path) -> syn::Result<Result<Self, Path>> { | ||||
|         match known_items::PhantomConstGet::parse_path_with_arguments(path) { | ||||
|             Ok((phantom_const_get, arguments)) => { | ||||
|                 Self::parse_path_and_arguments(phantom_const_get, arguments).map(Ok) | ||||
|             } | ||||
|             Err(path) => Ok(Err(path)), | ||||
|         } | ||||
|     } | ||||
|     pub(crate) fn parse_path_and_arguments( | ||||
|         phantom_const_get: known_items::PhantomConstGet, | ||||
|         arguments: PathArguments, | ||||
|     ) -> syn::Result<Self> { | ||||
|         let error = |arguments: PathArguments, message: &str| { | ||||
|             let mut path = phantom_const_get.path.clone(); | ||||
|             path.segments.last_mut().expect("known to exist").arguments = arguments; | ||||
|             syn::Error::new_spanned(path, message) | ||||
|         }; | ||||
|         match arguments { | ||||
|             PathArguments::None => Err(error(arguments, "missing generics for PhantomConstGet")), | ||||
|             PathArguments::AngleBracketed(AngleBracketedGenericArguments { | ||||
|                 colon2_token, | ||||
|                 lt_token, | ||||
|                 args, | ||||
|                 gt_token, | ||||
|             }) => { | ||||
|                 let error = |args: Punctuated<GenericArgument, Token![,]>, message| { | ||||
|                     error( | ||||
|                         PathArguments::AngleBracketed(AngleBracketedGenericArguments { | ||||
|                             colon2_token, | ||||
|                             lt_token, | ||||
|                             args, | ||||
|                             gt_token, | ||||
|                         }), | ||||
|                         message, | ||||
|                     ) | ||||
|                 }; | ||||
|                 let mut args = args.into_pairs().peekable(); | ||||
|                 let Some((generic_argument, comma_token)) = args.next().map(Pair::into_tuple) | ||||
|                 else { | ||||
|                     return Err(error( | ||||
|                         Default::default(), | ||||
|                         "PhantomConstGet takes a type argument but no generic arguments were supplied", | ||||
|                     )); | ||||
|                 }; | ||||
|                 if args.peek().is_some() { | ||||
|                     return Err(error( | ||||
|                         [Pair::new(generic_argument, comma_token)] | ||||
|                             .into_iter() | ||||
|                             .chain(args) | ||||
|                             .collect(), | ||||
|                         "PhantomConstGet takes a single type argument but too many generic arguments were supplied", | ||||
|                     )); | ||||
|                 }; | ||||
|                 let GenericArgument::Type(ty) = generic_argument else { | ||||
|                     return Err(error( | ||||
|                         Punctuated::from_iter([Pair::new(generic_argument, comma_token)]), | ||||
|                         "PhantomConstGet requires a type argument", | ||||
|                     )); | ||||
|                 }; | ||||
|                 Ok(Self { | ||||
|                     phantom_const_get, | ||||
|                     colon2_token, | ||||
|                     lt_token, | ||||
|                     ty, | ||||
|                     comma_token, | ||||
|                     gt_token, | ||||
|                 }) | ||||
|             } | ||||
|             PathArguments::Parenthesized(_) => Err(error( | ||||
|                 arguments, | ||||
|                 "parenthetical generics are not valid for PhantomConstGet", | ||||
|             )), | ||||
|         } | ||||
|     } | ||||
|     pub(crate) fn parse_type_param_bound( | ||||
|         bound: TypeParamBound, | ||||
|     ) -> syn::Result<Result<Self, TypeParamBound>> { | ||||
|         let TypeParamBound::Trait(TraitBound { | ||||
|             paren_token: None, | ||||
|             modifier: syn::TraitBoundModifier::None, | ||||
|             lifetimes: None, | ||||
|             path, | ||||
|         }) = bound | ||||
|         else { | ||||
|             return Ok(Err(bound)); | ||||
|         }; | ||||
|         Ok(match Self::parse_path_with_arguments(path)? { | ||||
|             Ok(v) => Ok(v), | ||||
|             Err(path) => Err(TypeParamBound::Trait(TraitBound { | ||||
|                 paren_token: None, | ||||
|                 modifier: syn::TraitBoundModifier::None, | ||||
|                 lifetimes: None, | ||||
|                 path, | ||||
|             })), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ToTokens for PhantomConstGetBound { | ||||
|     fn to_tokens(&self, tokens: &mut TokenStream) { | ||||
|         let Self { | ||||
|             phantom_const_get, | ||||
|             colon2_token, | ||||
|             lt_token, | ||||
|             ty, | ||||
|             comma_token, | ||||
|             gt_token, | ||||
|         } = self; | ||||
|         phantom_const_get.to_tokens(tokens); | ||||
|         colon2_token.to_tokens(tokens); | ||||
|         lt_token.to_tokens(tokens); | ||||
|         ty.to_tokens(tokens); | ||||
|         comma_token.to_tokens(tokens); | ||||
|         gt_token.to_tokens(tokens); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<PhantomConstGetBound> for Path { | ||||
|     fn from(value: PhantomConstGetBound) -> Self { | ||||
|         let PhantomConstGetBound { | ||||
|             phantom_const_get, | ||||
|             colon2_token, | ||||
|             lt_token, | ||||
|             ty, | ||||
|             comma_token, | ||||
|             gt_token, | ||||
|         } = value; | ||||
|         let mut path = phantom_const_get.path; | ||||
|         path.segments.last_mut().expect("known to exist").arguments = | ||||
|             PathArguments::AngleBracketed(AngleBracketedGenericArguments { | ||||
|                 colon2_token, | ||||
|                 lt_token, | ||||
|                 args: FromIterator::from_iter([Pair::new(GenericArgument::Type(ty), comma_token)]), | ||||
|                 gt_token, | ||||
|             }); | ||||
|         path | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<PhantomConstGetBound> for TraitBound { | ||||
|     fn from(value: PhantomConstGetBound) -> Self { | ||||
|         let path = Path::from(value); | ||||
|         TraitBound { | ||||
|             paren_token: None, | ||||
|             modifier: syn::TraitBoundModifier::None, | ||||
|             lifetimes: None, | ||||
|             path, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<PhantomConstGetBound> for TypeParamBound { | ||||
|     fn from(value: PhantomConstGetBound) -> Self { | ||||
|         TraitBound::from(value).into() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_bounds { | ||||
|     ( | ||||
|         #[struct = $struct_type:ident] | ||||
|  | @ -2072,6 +2240,10 @@ macro_rules! impl_bounds { | |||
|             $( | ||||
|                 $Variant:ident, | ||||
|             )* | ||||
|             $( | ||||
|                 #[has_body] | ||||
|                 $VariantHasBody:ident($variant_has_body_ty:ty), | ||||
|             )* | ||||
|             $( | ||||
|                 #[unknown] | ||||
|                 $Unknown:ident, | ||||
|  | @ -2081,6 +2253,7 @@ macro_rules! impl_bounds { | |||
|         #[derive(Clone, Debug)] | ||||
|         $vis enum $enum_type { | ||||
|             $($Variant(known_items::$Variant),)* | ||||
|             $($VariantHasBody($variant_has_body_ty),)* | ||||
|             $($Unknown(syn::TypeParamBound),)? | ||||
|         } | ||||
| 
 | ||||
|  | @ -2090,31 +2263,42 @@ macro_rules! impl_bounds { | |||
|             } | ||||
|         })* | ||||
| 
 | ||||
|         $(impl From<$variant_has_body_ty> for $enum_type { | ||||
|             fn from(v: $variant_has_body_ty) -> Self { | ||||
|                 Self::$VariantHasBody(v) | ||||
|             } | ||||
|         })* | ||||
| 
 | ||||
|         impl ToTokens for $enum_type { | ||||
|             fn to_tokens(&self, tokens: &mut TokenStream) { | ||||
|                 match self { | ||||
|                     $(Self::$Variant(v) => v.to_tokens(tokens),)* | ||||
|                     $(Self::$VariantHasBody(v) => v.to_tokens(tokens),)* | ||||
|                     $(Self::$Unknown(v) => v.to_tokens(tokens),)? | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $enum_type { | ||||
|             $vis fn parse_path(path: Path) -> Result<Self, Path> { | ||||
|             $vis fn parse_path_with_arguments(path: Path) -> syn::Result<Result<Self, Path>> { | ||||
|                 #![allow(unreachable_code)] | ||||
|                 $(let path = match known_items::$Variant::parse_path(path) { | ||||
|                     Ok(v) => return Ok(Self::$Variant(v)), | ||||
|                     Ok(v) => return Ok(Ok(Self::$Variant(v))), | ||||
|                     Err(path) => path, | ||||
|                 };)* | ||||
|                 $(return Ok(Self::$Unknown(syn::TraitBound { | ||||
|                 $(let path = match <$variant_has_body_ty>::parse_path_with_arguments(path)? { | ||||
|                     Ok(v) => return Ok(Ok(Self::$VariantHasBody(v))), | ||||
|                     Err(path) => path, | ||||
|                 };)* | ||||
|                 $(return Ok(Ok(Self::$Unknown(syn::TraitBound { | ||||
|                     paren_token: None, | ||||
|                     modifier: syn::TraitBoundModifier::None, | ||||
|                     lifetimes: None, | ||||
|                     path, | ||||
|                 }.into()));)? | ||||
|                 Err(path) | ||||
|                 }.into())));)? | ||||
|                 Ok(Err(path)) | ||||
|             } | ||||
|             $vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> Result<Self, syn::TypeParamBound> { | ||||
|             $vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> syn::Result<Result<Self, syn::TypeParamBound>> { | ||||
|                 #![allow(unreachable_code)] | ||||
|                 if let syn::TypeParamBound::Trait(mut trait_bound) = type_param_bound { | ||||
|                     if let syn::TraitBound { | ||||
|  | @ -2123,24 +2307,24 @@ macro_rules! impl_bounds { | |||
|                         lifetimes: None, | ||||
|                         path: _, | ||||
|                     } = trait_bound { | ||||
|                         match Self::parse_path(trait_bound.path) { | ||||
|                             Ok(retval) => return Ok(retval), | ||||
|                         match Self::parse_path_with_arguments(trait_bound.path)? { | ||||
|                             Ok(retval) => return Ok(Ok(retval)), | ||||
|                             Err(path) => trait_bound.path = path, | ||||
|                         } | ||||
|                     } | ||||
|                     type_param_bound = trait_bound.into(); | ||||
|                 } | ||||
|                 $(return Ok(Self::$Unknown(type_param_bound));)? | ||||
|                 Err(type_param_bound) | ||||
|                 $(return Ok(Ok(Self::$Unknown(type_param_bound)));)? | ||||
|                 Ok(Err(type_param_bound)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Parse for $enum_type { | ||||
|             fn parse(input: ParseStream) -> syn::Result<Self> { | ||||
|                 Self::parse_type_param_bound(input.parse()?) | ||||
|                 Self::parse_type_param_bound(input.parse()?)? | ||||
|                     .map_err(|type_param_bound| syn::Error::new_spanned( | ||||
|                         type_param_bound, | ||||
|                         format_args!("expected one of: {}", [$(stringify!($Variant)),*].join(", ")), | ||||
|                         format_args!("expected one of: {}", [$(stringify!($Variant),)* $(stringify!($VariantHasBody)),*].join(", ")), | ||||
|                     )) | ||||
|             } | ||||
|         } | ||||
|  | @ -2149,6 +2333,7 @@ macro_rules! impl_bounds { | |||
|         #[allow(non_snake_case)] | ||||
|         $vis struct $struct_type { | ||||
|             $($vis $Variant: Option<known_items::$Variant>,)* | ||||
|             $($vis $VariantHasBody: Option<$variant_has_body_ty>,)* | ||||
|             $($vis $Unknown: Vec<syn::TypeParamBound>,)? | ||||
|         } | ||||
| 
 | ||||
|  | @ -2161,6 +2346,11 @@ macro_rules! impl_bounds { | |||
|                     separator = Some(<Token![+]>::default()); | ||||
|                     v.to_tokens(tokens); | ||||
|                 })* | ||||
|                 $(if let Some(v) = &self.$VariantHasBody { | ||||
|                     separator.to_tokens(tokens); | ||||
|                     separator = Some(<Token![+]>::default()); | ||||
|                     v.to_tokens(tokens); | ||||
|                 })* | ||||
|                 $(for v in &self.$Unknown { | ||||
|                     separator.to_tokens(tokens); | ||||
|                     separator = Some(<Token![+]>::default()); | ||||
|  | @ -2174,6 +2364,7 @@ macro_rules! impl_bounds { | |||
|             #[allow(non_snake_case)] | ||||
|             $vis struct Iter { | ||||
|                 $($Variant: Option<known_items::$Variant>,)* | ||||
|                 $($VariantHasBody: Option<$variant_has_body_ty>,)* | ||||
|                 $($Unknown: std::vec::IntoIter<syn::TypeParamBound>,)? | ||||
|             } | ||||
| 
 | ||||
|  | @ -2184,6 +2375,7 @@ macro_rules! impl_bounds { | |||
|                 fn into_iter(self) -> Self::IntoIter { | ||||
|                     Iter { | ||||
|                         $($Variant: self.$Variant,)* | ||||
|                         $($VariantHasBody: self.$VariantHasBody,)* | ||||
|                         $($Unknown: self.$Unknown.into_iter(),)? | ||||
|                     } | ||||
|                 } | ||||
|  | @ -2198,6 +2390,11 @@ macro_rules! impl_bounds { | |||
|                             return Some($enum_type::$Variant(value)); | ||||
|                         } | ||||
|                     )* | ||||
|                     $( | ||||
|                         if let Some(value) = self.$VariantHasBody.take() { | ||||
|                             return Some($enum_type::$VariantHasBody(value)); | ||||
|                         } | ||||
|                     )* | ||||
|                     $( | ||||
|                         if let Some(value) = self.$Unknown.next() { | ||||
|                             return Some($enum_type::$Unknown(value)); | ||||
|  | @ -2213,6 +2410,11 @@ macro_rules! impl_bounds { | |||
|                             init = f(init, $enum_type::$Variant(value)); | ||||
|                         } | ||||
|                     )* | ||||
|                     $( | ||||
|                         if let Some(value) = self.$VariantHasBody.take() { | ||||
|                             init = f(init, $enum_type::$VariantHasBody(value)); | ||||
|                         } | ||||
|                     )* | ||||
|                     $( | ||||
|                         if let Some(value) = self.$Unknown.next() { | ||||
|                             init = f(init, $enum_type::$Unknown(value)); | ||||
|  | @ -2229,6 +2431,9 @@ macro_rules! impl_bounds { | |||
|                     $($enum_type::$Variant(v) => { | ||||
|                         self.$Variant = Some(v); | ||||
|                     })* | ||||
|                     $($enum_type::$VariantHasBody(v) => { | ||||
|                         self.$VariantHasBody = Some(v); | ||||
|                     })* | ||||
|                     $($enum_type::$Unknown(v) => { | ||||
|                         self.$Unknown.push(v); | ||||
|                     })? | ||||
|  | @ -2250,6 +2455,9 @@ macro_rules! impl_bounds { | |||
|                     $(if let Some(v) = v.$Variant { | ||||
|                         self.$Variant = Some(v); | ||||
|                     })* | ||||
|                     $(if let Some(v) = v.$VariantHasBody { | ||||
|                         self.$VariantHasBody = Some(v); | ||||
|                     })* | ||||
|                     $(self.$Unknown.extend(v.$Unknown);)* | ||||
|                 }); | ||||
|             } | ||||
|  | @ -2304,6 +2512,8 @@ impl_bounds! { | |||
|         Size, | ||||
|         StaticType, | ||||
|         Type, | ||||
|         #[has_body] | ||||
|         PhantomConstGet(PhantomConstGetBound), | ||||
|         #[unknown] | ||||
|         Unknown, | ||||
|     } | ||||
|  | @ -2319,6 +2529,8 @@ impl_bounds! { | |||
|         ResetType, | ||||
|         StaticType, | ||||
|         Type, | ||||
|         #[has_body] | ||||
|         PhantomConstGet(PhantomConstGetBound), | ||||
|         #[unknown] | ||||
|         Unknown, | ||||
|     } | ||||
|  | @ -2334,6 +2546,7 @@ impl From<ParsedTypeBound> for ParsedBound { | |||
|             ParsedTypeBound::ResetType(v) => ParsedBound::ResetType(v), | ||||
|             ParsedTypeBound::StaticType(v) => ParsedBound::StaticType(v), | ||||
|             ParsedTypeBound::Type(v) => ParsedBound::Type(v), | ||||
|             ParsedTypeBound::PhantomConstGet(v) => ParsedBound::PhantomConstGet(v), | ||||
|             ParsedTypeBound::Unknown(v) => ParsedBound::Unknown(v), | ||||
|         } | ||||
|     } | ||||
|  | @ -2349,6 +2562,7 @@ impl From<ParsedTypeBounds> for ParsedBounds { | |||
|             ResetType, | ||||
|             StaticType, | ||||
|             Type, | ||||
|             PhantomConstGet, | ||||
|             Unknown, | ||||
|         } = value; | ||||
|         Self { | ||||
|  | @ -2361,6 +2575,7 @@ impl From<ParsedTypeBounds> for ParsedBounds { | |||
|             Size: None, | ||||
|             StaticType, | ||||
|             Type, | ||||
|             PhantomConstGet, | ||||
|             Unknown, | ||||
|         } | ||||
|     } | ||||
|  | @ -2397,6 +2612,10 @@ impl ParsedTypeBound { | |||
|                 ParsedTypeBound::Type(known_items::Type(span)), | ||||
|             ]), | ||||
|             Self::Type(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::from(v)]), | ||||
|             Self::PhantomConstGet(v) => ParsedTypeBounds::from_iter([ | ||||
|                 ParsedTypeBound::from(v), | ||||
|                 ParsedTypeBound::Type(known_items::Type(span)), | ||||
|             ]), | ||||
|             Self::Unknown(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::Unknown(v)]), | ||||
|         } | ||||
|     } | ||||
|  | @ -2432,6 +2651,7 @@ impl From<ParsedSizeTypeBounds> for ParsedBounds { | |||
|             Size, | ||||
|             StaticType: None, | ||||
|             Type: None, | ||||
|             PhantomConstGet: None, | ||||
|             Unknown: vec![], | ||||
|         } | ||||
|     } | ||||
|  | @ -2534,6 +2754,9 @@ impl ParsedBound { | |||
|             Self::Size(v) => ParsedBoundCategory::SizeType(ParsedSizeTypeBound::Size(v)), | ||||
|             Self::StaticType(v) => ParsedBoundCategory::Type(ParsedTypeBound::StaticType(v)), | ||||
|             Self::Type(v) => ParsedBoundCategory::Type(ParsedTypeBound::Type(v)), | ||||
|             Self::PhantomConstGet(v) => { | ||||
|                 ParsedBoundCategory::Type(ParsedTypeBound::PhantomConstGet(v)) | ||||
|             } | ||||
|             Self::Unknown(v) => ParsedBoundCategory::Unknown(v), | ||||
|         } | ||||
|     } | ||||
|  | @ -3419,7 +3642,8 @@ impl ParsedGenerics { | |||
|                                 | ParsedTypeBound::BundleType(_) | ||||
|                                 | ParsedTypeBound::EnumType(_) | ||||
|                                 | ParsedTypeBound::IntType(_) | ||||
|                                 | ParsedTypeBound::ResetType(_) => { | ||||
|                                 | ParsedTypeBound::ResetType(_) | ||||
|                                 | ParsedTypeBound::PhantomConstGet(_) => { | ||||
|                                     errors.error(bound, "bounds on mask types are not implemented"); | ||||
|                                 } | ||||
|                                 ParsedTypeBound::StaticType(bound) => { | ||||
|  |  | |||
|  | @ -166,7 +166,7 @@ pub use fayalite_proc_macros::hdl_module; | |||
| /// // you can then use it in other types:
 | ||||
| ///
 | ||||
| /// #[hdl(no_static)]
 | ||||
| /// pub struct WrapMyArray<P: Type + PhantomConstGet<Config>> {
 | ||||
| /// pub struct WrapMyArray<P: PhantomConstGet<Config>> {
 | ||||
| ///     pub my_array: GetMyArray<P>,
 | ||||
| /// }
 | ||||
| ///
 | ||||
|  | @ -202,7 +202,7 @@ pub use fayalite_proc_macros::hdl_module; | |||
| /// // you can then use it in other types:
 | ||||
| ///
 | ||||
| /// #[hdl(no_static)]
 | ||||
| /// pub struct FlagPerItem<P: Type + PhantomConstGet<Config>> {
 | ||||
| /// pub struct FlagPerItem<P: PhantomConstGet<Config>> {
 | ||||
| ///     pub flags: ArrayType<Bool, GetItemsLen<P>>,
 | ||||
| /// }
 | ||||
| ///
 | ||||
|  |  | |||
|  | @ -210,7 +210,7 @@ pub type GetA<P: PhantomConstGet<MyPhantomConstInner>> = DynSize; | |||
| pub type GetB<P: PhantomConstGet<MyPhantomConstInner>> = UInt; | ||||
| 
 | ||||
| #[hdl(outline_generated, no_static)] | ||||
| pub struct MyTypeWithPhantomConstParameter<P: Type + PhantomConstGet<MyPhantomConstInner>> { | ||||
| pub struct MyTypeWithPhantomConstParameter<P: PhantomConstGet<MyPhantomConstInner>> { | ||||
|     pub a: ArrayType<Bool, GetA<P>>, | ||||
|     pub b: HdlOption<GetB<P>>, | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue