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