This commit is contained in:
parent
bf907c3872
commit
59cef3f398
3 changed files with 255 additions and 22 deletions
|
@ -1273,6 +1273,130 @@ make_parsed_type_or_const! {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct ParsedTypePhantomData {
|
||||
pub(crate) phantom_data: known_items::PhantomData,
|
||||
pub(crate) lt_token: Token![<],
|
||||
pub(crate) ty: Box<ParsedType>,
|
||||
pub(crate) gt_token: Token![>],
|
||||
}
|
||||
|
||||
impl_fold! {
|
||||
struct ParsedTypePhantomData<> {
|
||||
phantom_data: known_items::PhantomData,
|
||||
lt_token: Token![<],
|
||||
ty: Box<ParsedType>,
|
||||
gt_token: Token![>],
|
||||
}
|
||||
}
|
||||
|
||||
impl ParsedTypePhantomData {
|
||||
pub(crate) fn try_from_named(
|
||||
named: ParsedTypeNamed,
|
||||
parser: &mut TypesParser<'_>,
|
||||
) -> Result<Result<Self, ParsedTypeNamed>, ParseFailed> {
|
||||
let ParsedTypeNamed { path, args } = named;
|
||||
let parsed_path = known_items::PhantomData::parse_path(path);
|
||||
let phantom_data = match parsed_path {
|
||||
Ok(phantom_data) => phantom_data,
|
||||
Err(path) => return Ok(Err(ParsedTypeNamed { path, args })),
|
||||
};
|
||||
let Some(ParsedGenericArguments {
|
||||
colon2_token: _,
|
||||
lt_token,
|
||||
args,
|
||||
gt_token,
|
||||
}) = args
|
||||
else {
|
||||
parser
|
||||
.errors()
|
||||
.error(phantom_data, "PhantomData requires generic arguments");
|
||||
return Err(ParseFailed);
|
||||
};
|
||||
let args_len = args.len();
|
||||
if args_len != 1 {
|
||||
parser.errors().error(
|
||||
phantom_data,
|
||||
format_args!(
|
||||
"wrong number of generic arguments supplied: got {args_len}, expected 1"
|
||||
),
|
||||
);
|
||||
return Err(ParseFailed);
|
||||
}
|
||||
let ty = args.into_iter().next().unwrap();
|
||||
let ParsedGenericArgument::Type(ty) = ty else {
|
||||
parser.errors().error(ty, "expected a type");
|
||||
return Err(ParseFailed);
|
||||
};
|
||||
Ok(Ok(Self {
|
||||
phantom_data,
|
||||
lt_token,
|
||||
ty: Box::new(ty),
|
||||
gt_token,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParsedTypePhantomData> for Type {
|
||||
fn from(value: ParsedTypePhantomData) -> Type {
|
||||
let ParsedTypePhantomData {
|
||||
phantom_data,
|
||||
lt_token,
|
||||
ty,
|
||||
gt_token,
|
||||
} = value;
|
||||
let path = phantom_data.path;
|
||||
let mut args = Punctuated::new();
|
||||
args.push(GenericArgument::Type(ty.into()));
|
||||
let args = AngleBracketedGenericArguments {
|
||||
colon2_token: Some(Token),
|
||||
lt_token,
|
||||
args,
|
||||
gt_token,
|
||||
};
|
||||
let mut segments = path.segments;
|
||||
segments.last_mut().unwrap().arguments = PathArguments::AngleBracketed(args);
|
||||
Type::Path(TypePath {
|
||||
qself: None,
|
||||
path: Path {
|
||||
leading_colon: path.leading_colon,
|
||||
segments,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl MakeHdlTypeExpr for ParsedTypePhantomData {
|
||||
fn make_hdl_type_expr(&self, _context: &MakeHdlTypeExprContext) -> Expr {
|
||||
let ParsedTypePhantomData {
|
||||
phantom_data,
|
||||
lt_token: _,
|
||||
ty: _,
|
||||
gt_token: _,
|
||||
} = self;
|
||||
Expr::Path(ExprPath {
|
||||
attrs: vec![],
|
||||
qself: None,
|
||||
path: phantom_data.path.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ParsedTypePhantomData {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let Self {
|
||||
phantom_data,
|
||||
lt_token,
|
||||
ty,
|
||||
gt_token,
|
||||
} = self;
|
||||
phantom_data.to_tokens(tokens);
|
||||
lt_token.to_tokens(tokens);
|
||||
ty.to_tokens(tokens);
|
||||
gt_token.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum ParsedType {
|
||||
Delimited(ParsedTypeDelimited),
|
||||
|
@ -1280,6 +1404,7 @@ pub(crate) enum ParsedType {
|
|||
NamedParam(ParsedTypeNamedParam),
|
||||
Tuple(ParsedTypeTuple),
|
||||
ConstUsize(ParsedTypeConstUsize),
|
||||
PhantomData(ParsedTypePhantomData),
|
||||
Array(ParsedTypeArray),
|
||||
UInt(ParsedTypeUInt),
|
||||
SInt(ParsedTypeSInt),
|
||||
|
@ -1294,6 +1419,7 @@ impl_fold! {
|
|||
NamedParam(ParsedTypeNamedParam),
|
||||
Tuple(ParsedTypeTuple),
|
||||
ConstUsize(ParsedTypeConstUsize),
|
||||
PhantomData(ParsedTypePhantomData),
|
||||
Array(ParsedTypeArray),
|
||||
UInt(ParsedTypeUInt),
|
||||
SInt(ParsedTypeSInt),
|
||||
|
@ -1310,6 +1436,7 @@ impl From<ParsedType> for Type {
|
|||
ParsedType::NamedParam(v) => v.into(),
|
||||
ParsedType::Tuple(v) => v.into(),
|
||||
ParsedType::ConstUsize(v) => v.into(),
|
||||
ParsedType::PhantomData(v) => v.into(),
|
||||
ParsedType::Array(v) => v.into(),
|
||||
ParsedType::UInt(v) => v.into(),
|
||||
ParsedType::SInt(v) => v.into(),
|
||||
|
@ -1360,6 +1487,7 @@ impl ToTokens for ParsedType {
|
|||
ParsedType::Named(ty) => ty.to_tokens(tokens),
|
||||
ParsedType::Tuple(ty) => ty.to_tokens(tokens),
|
||||
ParsedType::ConstUsize(ty) => ty.to_tokens(tokens),
|
||||
ParsedType::PhantomData(ty) => ty.to_tokens(tokens),
|
||||
ParsedType::Array(ty) => ty.to_tokens(tokens),
|
||||
ParsedType::UInt(ty) => ty.to_tokens(tokens),
|
||||
ParsedType::SInt(ty) => ty.to_tokens(tokens),
|
||||
|
@ -1467,6 +1595,10 @@ impl ParseTypes<Path> for ParsedType {
|
|||
Ok(v) => return Ok(Self::ConstUsize(v)),
|
||||
Err(named) => named,
|
||||
};
|
||||
let named = match ParsedTypePhantomData::try_from_named(named, parser)? {
|
||||
Ok(v) => return Ok(Self::PhantomData(v)),
|
||||
Err(named) => named,
|
||||
};
|
||||
let named = match ParsedTypeUInt::try_from_named(named, parser)? {
|
||||
Ok(v) => return Ok(Self::UInt(v)),
|
||||
Err(named) => named,
|
||||
|
@ -1784,7 +1916,7 @@ pub(crate) mod known_items {
|
|||
|
||||
#[allow(non_snake_case, dead_code)]
|
||||
pub(crate) fn $known_item(span: Span) -> $known_item {
|
||||
let segments = $known_item::PATH_SEGMENTS.iter()
|
||||
let segments = $known_item::PATH_SEGMENTS[0].iter()
|
||||
.copied()
|
||||
.map(|seg| PathSegment::from(Ident::new(seg, span)))
|
||||
.collect();
|
||||
|
@ -1810,20 +1942,21 @@ pub(crate) mod known_items {
|
|||
return Ok(Self { span: ident.span(), path });
|
||||
}
|
||||
}
|
||||
if path.segments.len() == Self::PATH_SEGMENTS.len()
|
||||
&& path
|
||||
.segments
|
||||
.iter()
|
||||
.zip(Self::PATH_SEGMENTS)
|
||||
.all(|(seg, expected)| {
|
||||
matches!(seg.arguments, PathArguments::None)
|
||||
&& seg.ident == *expected
|
||||
})
|
||||
{
|
||||
Ok(Self { span: path.segments.last().unwrap().ident.span(), path })
|
||||
} else {
|
||||
Err(path)
|
||||
for &path_segments in Self::PATH_SEGMENTS.iter() {
|
||||
if path.segments.len() == path_segments.len()
|
||||
&& path
|
||||
.segments
|
||||
.iter()
|
||||
.zip(path_segments)
|
||||
.all(|(seg, expected)| {
|
||||
matches!(seg.arguments, PathArguments::None)
|
||||
&& seg.ident == *expected
|
||||
})
|
||||
{
|
||||
return Ok(Self { span: path.segments.last().unwrap().ident.span(), path });
|
||||
}
|
||||
}
|
||||
Err(path)
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn parse_path_with_arguments(mut path: Path) -> Result<(Self, PathArguments), Path> {
|
||||
|
@ -1878,19 +2011,24 @@ pub(crate) mod known_items {
|
|||
}
|
||||
|
||||
macro_rules! impl_known_item {
|
||||
($([$(::$head:ident)*])? ::$next:ident $(::$tail:ident)+) => {
|
||||
impl_known_item!([$($(::$head)*)? ::$next] $(::$tail)+);
|
||||
};
|
||||
([$(::$seg:ident)+] ::$known_item:ident) => {
|
||||
($(#[alias = $(::$alias:ident)+])* [$(::$seg:ident)+] ::$known_item:ident) => {
|
||||
impl_known_item_body!($known_item);
|
||||
|
||||
impl $known_item {
|
||||
pub(crate) const PATH_SEGMENTS: &'static [&'static str] = &[
|
||||
$(stringify!($seg),)+
|
||||
stringify!($known_item),
|
||||
pub(crate) const PATH_SEGMENTS: &'static [&'static [&'static str]] = &[
|
||||
&[
|
||||
$(stringify!($seg),)+
|
||||
stringify!($known_item),
|
||||
],
|
||||
$(&[
|
||||
$(stringify!($alias),)+
|
||||
],)*
|
||||
];
|
||||
}
|
||||
};
|
||||
($(#[alias = $(::$alias:ident)+])* $([$(::$head:ident)*])? ::$next:ident $(::$tail:ident)+) => {
|
||||
impl_known_item!($(#[alias = $(::$alias)+])* [$($(::$head)*)? ::$next] $(::$tail)+);
|
||||
};
|
||||
}
|
||||
|
||||
impl_known_item!(::fayalite::array::Array);
|
||||
|
@ -1911,7 +2049,16 @@ pub(crate) mod known_items {
|
|||
impl_known_item!(::fayalite::ty::Type);
|
||||
impl_known_item!(::fayalite::ty::Type::MaskType);
|
||||
impl_known_item!(::fayalite::util::ConstUsize);
|
||||
impl_known_item!(::fayalite::__std::primitive::usize);
|
||||
impl_known_item!(
|
||||
#[alias = ::std::primitive::usize]
|
||||
#[alias = ::core::primitive::usize]
|
||||
::fayalite::__std::primitive::usize
|
||||
);
|
||||
impl_known_item!(
|
||||
#[alias = ::std::marker::PhantomData]
|
||||
#[alias = ::core::marker::PhantomData]
|
||||
::fayalite::__std::marker::PhantomData
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! impl_bounds {
|
||||
|
@ -3969,6 +4116,7 @@ impl MakeHdlTypeExpr for ParsedType {
|
|||
Self::NamedParam(v) => v.make_hdl_type_expr(context),
|
||||
Self::Tuple(v) => v.make_hdl_type_expr(context),
|
||||
Self::ConstUsize(v) => v.make_hdl_type_expr(context),
|
||||
Self::PhantomData(v) => v.make_hdl_type_expr(context),
|
||||
Self::Array(v) => v.make_hdl_type_expr(context),
|
||||
Self::UInt(v) => v.make_hdl_type_expr(context),
|
||||
Self::SInt(v) => v.make_hdl_type_expr(context),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue