Fixed type/generics parsing

This commit is contained in:
2026-06-04 18:50:33 +02:00
parent 6cacfd7135
commit 202f41c0e6
6 changed files with 28 additions and 40 deletions
+7 -12
View File
@@ -208,19 +208,14 @@ pub fn get_static_type_path(path: &Path) -> String {
impl GetRust for TypeExprKind { impl GetRust for TypeExprKind {
fn get_rust(&self) -> String { fn get_rust(&self) -> String {
match self { match self {
TypeExprKind::Path(path) => get_static_type_path(path), TypeExprKind::Path(path, generics) => {
TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()), if let Some(generics) = generics {
TypeExprKind::PathParams(path, params) => { format!("{}{}", get_static_type_path(path), generics.get_rust())
format!( } else {
"{}<{}>", get_static_type_path(path)
get_static_type_path(path), }
params
.into_iter()
.map(|t| t.get_rust())
.collect::<Vec<_>>()
.join(", ")
)
} }
TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()),
TypeExprKind::Tuple(types) => format!( TypeExprKind::Tuple(types) => format!(
"({})", "({})",
types types
+5 -3
View File
@@ -235,7 +235,7 @@ impl GenRust for (&Vec<Spanned<FieldDeclStmt>>, &Spanned<ClassConstructor>) {
let mut constructor_params = vec![VarDecl { let mut constructor_params = vec![VarDecl {
name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])), name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])),
type_: Some(TypeExpr( type_: Some(TypeExpr(
TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))])), TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))]), None),
vec![TypePostfix::RefMut], vec![TypePostfix::RefMut],
)), )),
}]; }];
@@ -423,8 +423,10 @@ impl GenRust for TopLevelKind {
let mut impl_ = impl_.clone(); let mut impl_ = impl_.clone();
impl_.item.trait_ = Some(impl_.item.target); impl_.item.trait_ = Some(impl_.item.target);
impl_.item.target = impl_.item.target = TypeExpr(
TypeExpr(TypeExprKind::Path(Path(vec![name.clone()])), Vec::new()); TypeExprKind::Path(Path(vec![name.clone()]), None),
Vec::new(),
);
impl_.gen_rust(ctx, cg); impl_.gen_rust(ctx, cg);
} }
+5 -5
View File
@@ -31,8 +31,7 @@ pub enum TypePostfix {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum TypeExprKind { pub enum TypeExprKind {
Path(Path), Path(Path, Option<Generics>),
PathParams(Path, Vec<TypeExpr>),
Tuple(Vec<TypeExpr>), Tuple(Vec<TypeExpr>),
Lifetime(Identifier), Lifetime(Identifier),
} }
@@ -54,9 +53,10 @@ impl From<GenericDecl> for Generic {
fn from(value: GenericDecl) -> Self { fn from(value: GenericDecl) -> Self {
match value { match value {
GenericDecl::Lifetime(life) => Generic::Lifetime(life), GenericDecl::Lifetime(life) => Generic::Lifetime(life),
GenericDecl::Type(ty, _) => { GenericDecl::Type(ty, _) => Generic::Type(TypeExpr(
Generic::Type(TypeExpr(TypeExprKind::Path(Path(vec![ty])), Vec::new())) TypeExprKind::Path(Path(vec![ty]), None),
} Vec::new(),
)),
} }
} }
} }
+4 -9
View File
@@ -80,10 +80,10 @@ let_kw = { "let" }
// ====================================================== // ======================================================
// GENERICS // GENERICS
// ====================================================== // ======================================================
generic_decl = { lifetime | (identifier ~ (":" ~ type_expr_param ~ ("+" ~ type_expr_param)*)?) } generic_decl = { lifetime | (identifier ~ (":" ~ generic ~ ("+" ~ generic)*)?) }
generics_decl = { "<" ~ (generic_decl ~ ("," ~ generic_decl)*)? ~ ">" } generics_decl = { "<" ~ (generic_decl ~ ("," ~ generic_decl)*)? ~ ">" }
generic = { lifetime | type_expr_param } generic = { lifetime | type_expr }
generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" } generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" }
// ====================================================== // ======================================================
@@ -95,7 +95,7 @@ tuple_type = {
} }
path_type = { path_type = {
static_path ~ ("<" ~ (type_expr_param ~ ("," ~ type_expr_param)*)? ~ ">")? static_path ~ generics?
} }
ref_type = { ref_type = {
@@ -114,11 +114,6 @@ lifetime = {
"'" ~ identifier "'" ~ identifier
} }
type_expr_param = {
type_expr
| lifetime
}
// ====================================================== // ======================================================
// LITERALS // LITERALS
// ====================================================== // ======================================================
@@ -308,7 +303,7 @@ impl_decl = {
// ====================================================== // ======================================================
// Traits // Traits
// ====================================================== // ======================================================
trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } trait_requirements = { ":" ~ generic ~ ("+" ~ generic)* }
trait_item = _{ trait_item = _{
function_decl function_decl
+6 -10
View File
@@ -2,7 +2,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure, ast_expr,
error::{AstError, GetLength, IntoErr, collect_recovered}, error::{AstError, IntoErr, collect_recovered},
parser::{consume_rule, listen_rule}, parser::{consume_rule, listen_rule},
}; };
@@ -53,14 +53,10 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExprKind {
match rule { match rule {
Rule::tuple_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))), Rule::tuple_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))),
Rule::path_type => { Rule::path_type => {
let path = Path::try_from(inner.next().unwrap()); ast_expr!(TypeExprKind::Path(
let params = collect_recovered(inner); Path::try_from(inner.next().unwrap()),
inner.next().map(Generics::try_from).transpose()
if params.len() == 0 { ))
ast_expr!(TypeExprKind::Path(path))
} else {
ast_expr!(TypeExprKind::PathParams(path, params))
}
} }
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
} }
@@ -75,11 +71,11 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
match rule { match rule {
Rule::generic => Self::try_from(inner.next().unwrap()),
Rule::type_expr => ast_expr!(TypeExpr( Rule::type_expr => ast_expr!(TypeExpr(
inner.next().unwrap().try_into(), inner.next().unwrap().try_into(),
collect_recovered(inner), collect_recovered(inner),
)), )),
Rule::type_expr_param => Self::try_from(inner.next().unwrap()),
Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into())) Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into()))
.get_map(TypeExpr::no_px) .get_map(TypeExpr::no_px)
.map(TypeExpr::no_px), .map(TypeExpr::no_px),
+1 -1
View File
@@ -30,7 +30,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
VarDecl { VarDecl {
name: name.clone(), name: name.clone(),
type_: Some(TypeExpr( type_: Some(TypeExpr(
TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])), TypeExprKind::Path(Path(vec![Identifier("Self".to_string())]), None),
if is_ref { if is_ref {
vec![if mutable { vec![if mutable {
TypePostfix::RefMut TypePostfix::RefMut