From f07bde8d3fa8fabbba758b472efacf12967444bd Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 16 Jun 2026 03:59:28 +0200 Subject: [PATCH] Unsafe lifetime --- crates/codegen/src/lib.rs | 22 ++++++++++++++++++---- crates/parser/src/ast/mod.rs | 8 +++++++- crates/parser/src/grammar.pest | 5 ++++- crates/parser/src/parser/common/types.rs | 4 ++-- crates/parser/src/parser/items/function.rs | 19 +++++++++++++++++-- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 6b17a85..9fac9df 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -236,12 +236,26 @@ impl GetRust for TypeExpr { mutable, ty, } => { - let mutable = if *mutable { "mut " } else { "" }; - if let Some(lifetime) = lifetime { - format!("&'{} {mutable}{}", lifetime.get_rust(), ty.get_rust()) + match lifetime { + Lifetime::Lifetime(v) => { + format!( + "&{} {}{}", + v.get_rust(), + if *mutable { "mut " } else { "" }, + ty.get_rust() + ) + } + Lifetime::Unsafe => { + format!( + "*{} {}", + if *mutable { "mut" } else { "const" }, + ty.get_rust() + ) + } + } } else { - format!("&{mutable}{}", ty.get_rust()) + format!("&{}{}", if *mutable { "mut " } else { "" }, ty.get_rust()) } } diff --git a/crates/parser/src/ast/mod.rs b/crates/parser/src/ast/mod.rs index 28e8cf8..04e6d4b 100644 --- a/crates/parser/src/ast/mod.rs +++ b/crates/parser/src/ast/mod.rs @@ -17,10 +17,16 @@ pub struct Identifier(pub String); #[derive(Debug, Clone, Serialize, Default)] pub struct ParamList(pub Vec); +#[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)] +pub enum Lifetime { + Lifetime(Identifier), + Unsafe, +} + #[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)] pub enum TypeExpr { Ref { - lifetime: Option, + lifetime: Option, mutable: bool, ty: Box, }, diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 9451996..5af7c30 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -82,6 +82,7 @@ module_program = { visibility = { "pub" ~ ("(" ~ static_path ~ ")")? } mutable = { "mut" } +unsafe_kw = { "unsafe" } // ====================================================== // GENERICS @@ -104,8 +105,10 @@ path_type = { static_path ~ generics? } +ref_lifetime = { lifetime | unsafe_kw } + ref_type = { - "*" ~ lifetime? ~ mutable? ~ type_expr + "*" ~ ref_lifetime? ~ mutable? ~ type_expr } dyn_type = { diff --git a/crates/parser/src/parser/common/types.rs b/crates/parser/src/parser/common/types.rs index fc610f0..3d2fa2b 100644 --- a/crates/parser/src/parser/common/types.rs +++ b/crates/parser/src/parser/common/types.rs @@ -28,8 +28,8 @@ impl<'a> TryFrom> for TypeExpr { Rule::ref_type => { ast_expr!(TypeExpr::Ref { - lifetime: consume_rule(&mut inner, Rule::lifetime) - .map(|v| v.into_inner().next().map(Identifier::try_from)) + lifetime: consume_rule(&mut inner, Rule::ref_lifetime) + .map(|v| v.into_inner().next().map(Lifetime::try_from)) .unwrap_or_default() .transpose(), mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult, diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 27da885..ef37078 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -2,7 +2,7 @@ use crate::{ Rule, ast::*, ast_ensure, ast_expr, - error::{AstError, AstResult, IntoErr}, + error::{self, AstError, AstResult, IntoErr}, parser::{consume_rule, listen_rule}, }; @@ -39,7 +39,7 @@ impl<'a> TryFrom> for FunctionDecl { type_: Some(if is_ref { TypeExpr::Ref { lifetime: - lifetime.map(|v| Identifier::try_from(v.into_inner().next().unwrap())) + lifetime.map(|v| Lifetime::try_from(v.into_inner().next().unwrap())) .transpose() .expect("Failed to get lifetime identifier"), mutable, @@ -88,3 +88,18 @@ impl<'a> TryFrom> for Override { }) } } + +impl<'a> TryFrom> for Lifetime { + type Error = AstError<'a, Self>; + + fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { + let mut inner = pair.clone().into_inner(); + + match pair.as_rule() { + Rule::ref_lifetime => inner.next().unwrap().try_into(), + Rule::lifetime => ast_expr!(Lifetime::Lifetime(inner.next().unwrap().try_into())), + Rule::unsafe_kw => Ok(Lifetime::Unsafe), + _ => error::AstError::bug_unimplemented(pair), + } + } +}