Unsafe lifetime

This commit is contained in:
2026-06-16 03:59:28 +02:00
parent d7e5e72bbb
commit f07bde8d3f
5 changed files with 48 additions and 10 deletions
+18 -4
View File
@@ -236,12 +236,26 @@ impl GetRust for TypeExpr {
mutable, mutable,
ty, ty,
} => { } => {
let mutable = if *mutable { "mut " } else { "" };
if let Some(lifetime) = lifetime { 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 { } else {
format!("&{mutable}{}", ty.get_rust()) format!("&{}{}", if *mutable { "mut " } else { "" }, ty.get_rust())
} }
} }
+7 -1
View File
@@ -17,10 +17,16 @@ pub struct Identifier(pub String);
#[derive(Debug, Clone, Serialize, Default)] #[derive(Debug, Clone, Serialize, Default)]
pub struct ParamList(pub Vec<VarDecl>); pub struct ParamList(pub Vec<VarDecl>);
#[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)]
pub enum Lifetime {
Lifetime(Identifier),
Unsafe,
}
#[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Serialize, PartialEq, Eq, Hash)]
pub enum TypeExpr { pub enum TypeExpr {
Ref { Ref {
lifetime: Option<Identifier>, lifetime: Option<Lifetime>,
mutable: bool, mutable: bool,
ty: Box<TypeExpr>, ty: Box<TypeExpr>,
}, },
+4 -1
View File
@@ -82,6 +82,7 @@ module_program = {
visibility = { "pub" ~ ("(" ~ static_path ~ ")")? } visibility = { "pub" ~ ("(" ~ static_path ~ ")")? }
mutable = { "mut" } mutable = { "mut" }
unsafe_kw = { "unsafe" }
// ====================================================== // ======================================================
// GENERICS // GENERICS
@@ -104,8 +105,10 @@ path_type = {
static_path ~ generics? static_path ~ generics?
} }
ref_lifetime = { lifetime | unsafe_kw }
ref_type = { ref_type = {
"*" ~ lifetime? ~ mutable? ~ type_expr "*" ~ ref_lifetime? ~ mutable? ~ type_expr
} }
dyn_type = { dyn_type = {
+2 -2
View File
@@ -28,8 +28,8 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
Rule::ref_type => { Rule::ref_type => {
ast_expr!(TypeExpr::Ref { ast_expr!(TypeExpr::Ref {
lifetime: consume_rule(&mut inner, Rule::lifetime) lifetime: consume_rule(&mut inner, Rule::ref_lifetime)
.map(|v| v.into_inner().next().map(Identifier::try_from)) .map(|v| v.into_inner().next().map(Lifetime::try_from))
.unwrap_or_default() .unwrap_or_default()
.transpose(), .transpose(),
mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<bool>, mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<bool>,
+17 -2
View File
@@ -2,7 +2,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure, ast_expr,
error::{AstError, AstResult, IntoErr}, error::{self, AstError, AstResult, IntoErr},
parser::{consume_rule, listen_rule}, parser::{consume_rule, listen_rule},
}; };
@@ -39,7 +39,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
type_: Some(if is_ref { type_: Some(if is_ref {
TypeExpr::Ref { TypeExpr::Ref {
lifetime: lifetime:
lifetime.map(|v| Identifier::try_from(v.into_inner().next().unwrap())) lifetime.map(|v| Lifetime::try_from(v.into_inner().next().unwrap()))
.transpose() .transpose()
.expect("Failed to get lifetime identifier"), .expect("Failed to get lifetime identifier"),
mutable, mutable,
@@ -88,3 +88,18 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Override {
}) })
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Lifetime {
type Error = AstError<'a, Self>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
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),
}
}
}