diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs index bc64081..0b4e2d7 100644 --- a/reid/src/mir/display.rs +++ b/reid/src/mir/display.rs @@ -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}}"), - } - } -} diff --git a/reid/src/mir/impl.rs b/reid/src/mir/impl.rs index 22428b3..3c401e8 100644 --- a/reid/src/mir/impl.rs +++ b/reid/src/mir/impl.rs @@ -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, } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 715d577..afb0270 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -109,18 +109,21 @@ pub enum TypeKind { Array(Box, u64), #[error("{0}")] CustomType(String), - #[error("Ptr({0})")] + #[error("Borrow({0})")] Borrow(Box), #[error("Ptr({0})")] Ptr(Box), - #[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), } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 9f06c7b..7d24570 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -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())), } } diff --git a/reid/src/mir/typerefs.rs b/reid/src/mir/typerefs.rs index 70ccf2a..15230cb 100644 --- a/reid/src/mir/typerefs.rs +++ b/reid/src/mir/typerefs.rs @@ -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 diff --git a/reid_src/borrow.reid b/reid_src/borrow.reid index cb52e06..ca96715 100644 --- a/reid_src/borrow.reid +++ b/reid_src/borrow.reid @@ -7,5 +7,5 @@ fn main() -> u32 { let mut borrow = &value; *borrow = 17; - return borrow; + return *borrow; }