From 1fadaa60f22cbefd4feab72d887c01f95f211cd3 Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 21 Jul 2025 10:33:37 +0300 Subject: [PATCH] Add mutability compatibility check to borrows --- reid/src/mir/implement.rs | 16 ++++++++++++---- reid/src/mir/mod.rs | 2 +- reid/src/mir/typecheck.rs | 2 ++ reid_src/borrow_hard.reid | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index 889155d..ba46bdc 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -385,10 +385,18 @@ impl Collapsable for TypeKind { (TypeKind::Vague(Vague::Unknown), other) | (other, TypeKind::Vague(Vague::Unknown)) => { Ok(other.clone()) } - (TypeKind::Borrow(val1, mut1), TypeKind::Borrow(val2, mut2)) => Ok(TypeKind::Borrow( - Box::new(val1.collapse_into(val2)?), - *mut1 && *mut2, - )), + (TypeKind::Borrow(val1, mut1), TypeKind::Borrow(val2, mut2)) => { + // Extracted to give priority for other collapse-error + let collapsed = val1.collapse_into(val2)?; + if mut1 == mut2 { + Ok(TypeKind::Borrow(Box::new(collapsed), *mut1 && *mut2)) + } else { + Err(ErrorKind::TypesDifferMutability( + self.clone(), + other.clone(), + )) + } + } _ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())), } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index e0bdb5c..f432a8c 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -109,7 +109,7 @@ pub enum TypeKind { Array(Box, u64), #[error("{0}")] CustomType(String), - #[error("Borrow({0})")] + #[error("Borrow({0}, {1})")] Borrow(Box, bool), #[error("Ptr({0})")] Ptr(Box), diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 2a1cb25..6247610 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -59,6 +59,8 @@ pub enum ErrorKind { InvalidSetExpression, #[error("Can not deref {0}, as it is not a borrow")] AttemptedDerefNonBorrow(String), + #[error("Types {0} and {1} differ in mutability")] + TypesDifferMutability(TypeKind, TypeKind), } /// Struct used to implement a type-checking pass that can be performed on the diff --git a/reid_src/borrow_hard.reid b/reid_src/borrow_hard.reid index 38fe32e..a074d51 100644 --- a/reid_src/borrow_hard.reid +++ b/reid_src/borrow_hard.reid @@ -5,7 +5,7 @@ fn changer(param: &mut u32) { } fn main() -> u32 { - let mut value = 6; + let value = 6; changer(&mut value);