Nearly get typechecking working for deref/borrow

This commit is contained in:
Sofia 2025-07-20 22:15:16 +03:00
parent 62d73b19a2
commit 47fa5f342f
6 changed files with 22 additions and 21 deletions

View File

@ -311,13 +311,3 @@ fn write_access(f: &mut std::fmt::Formatter<'_>, name: &String) -> std::fmt::Res
f.write_char('.')?;
Display::fmt(name, f)
}
impl std::fmt::Display for VagueType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
VagueType::Unknown => write!(f, "Unknown"),
VagueType::Number => write!(f, "Number"),
VagueType::TypeRef(_) => write!(f, "{{unknown}}"),
}
}
}

View File

@ -339,6 +339,7 @@ impl TypeKind {
let resolved = self.resolve_weak(refs);
match resolved {
TypeKind::Array(t, len) => TypeKind::Array(Box::new(t.resolve_ref(refs)), len),
TypeKind::Borrow(inner) => TypeKind::Borrow(Box::new(inner.resolve_ref(refs))),
_ => resolved,
}
}

View File

@ -109,18 +109,21 @@ pub enum TypeKind {
Array(Box<TypeKind>, u64),
#[error("{0}")]
CustomType(String),
#[error("Ptr({0})")]
#[error("Borrow({0})")]
Borrow(Box<TypeKind>),
#[error("Ptr({0})")]
Ptr(Box<TypeKind>),
#[error("{0}")]
Vague(VagueType),
#[error(transparent)]
Vague(#[from] VagueType),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error, PartialOrd, Ord, Hash)]
pub enum VagueType {
#[error("Unknown")]
Unknown,
#[error("Number")]
Number,
#[error("TypeRef({0})")]
TypeRef(usize),
}

View File

@ -669,16 +669,15 @@ impl Expression {
.resolve_ref(typerefs);
// Update typing to be more accurate
var_ref.0 = state.or_else(
let TypeKind::Borrow(inner) = state.or_else(
var_ref.0.resolve_ref(typerefs).collapse_into(&existing),
TypeKind::Vague(Vague::Unknown),
var_ref.2,
);
) else {
return Err(ErrorKind::AttemptedDerefNonBorrow(var_ref.1.clone()));
};
match &var_ref.0 {
TypeKind::Borrow(type_kind) => Ok(*type_kind.clone()),
_ => Err(ErrorKind::AttemptedDerefNonBorrow(var_ref.1.clone())),
}
Ok(*inner)
}
}
}
@ -760,6 +759,9 @@ impl Collapsable for TypeKind {
(TypeKind::Vague(Vague::Unknown), other) | (other, TypeKind::Vague(Vague::Unknown)) => {
Ok(other.clone())
}
(TypeKind::Borrow(val1), TypeKind::Borrow(val2)) => {
Ok(TypeKind::Borrow(Box::new(val1.collapse_into(val2)?)))
}
_ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())),
}
}

View File

@ -163,6 +163,11 @@ impl<'outer> ScopeTypeRefs<'outer> {
self.types
.new(&TypeKind::Array(Box::new(elem_ty.as_type()), *length))
}
TypeKind::Borrow(ty) => {
let inner_ty = self.from_type(ty)?;
self.types
.new(&&TypeKind::Borrow(Box::new(inner_ty.as_type())))
}
_ => {
if let Some(ty_ref) = self.types.find(ty) {
ty_ref

View File

@ -7,5 +7,5 @@ fn main() -> u32 {
let mut borrow = &value;
*borrow = 17;
return borrow;
return *borrow;
}