diff --git a/reid/src/lib.rs b/reid/src/lib.rs index 2eff622..a4ba55a 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -93,6 +93,7 @@ pub fn compile(source: &str) -> Result { let state = mir_context.pass(&mut TypeInference { refs: &refs }); dbg!(&state, &refs); + dbg!(&mir_context); println!("{}", &mir_context); let state = mir_context.pass(&mut TypeCheck { refs: &refs }); diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index e8d070b..3778608 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -254,17 +254,19 @@ impl Expression { ) -> Result { match &mut self.0 { ExprKind::Variable(var_ref) => { - let existing = state.or_else( - state - .scope - .variables - .get(&var_ref.1) - .map(|var| &var.ty) - .cloned() - .ok_or(ErrorKind::VariableNotDefined(var_ref.1.clone())), - Vague(Unknown), - var_ref.2, - ); + let existing = state + .or_else( + state + .scope + .variables + .get(&var_ref.1) + .map(|var| &var.ty) + .cloned() + .ok_or(ErrorKind::VariableNotDefined(var_ref.1.clone())), + Vague(Unknown), + var_ref.2, + ) + .resolve_hinted(hints); // Update typing to be more accurate var_ref.0 = state.or_else( @@ -339,9 +341,9 @@ impl Expression { .collapse_into(&function_call.return_type.resolve_hinted(hints))?; // Update typing to be more accurate function_call.return_type = ret_t.clone(); - Ok(ret_t) + Ok(ret_t.resolve_hinted(hints)) } else { - Ok(function_call.return_type.clone()) + Ok(function_call.return_type.clone().resolve_hinted(hints)) } } ExprKind::If(IfExpression(cond, lhs, rhs)) => { @@ -379,9 +381,15 @@ impl Expression { } ExprKind::Block(block) => block.typecheck(state, &hints, hint_t), ExprKind::Index(expression, idx) => { + // Try to unwrap hint type from array if possible + let hint_t = hint_t.map(|t| match t { + Array(type_kind, _) => &type_kind, + _ => t, + }); + let expr_t = expression.typecheck(state, hints, hint_t)?; if let TypeKind::Array(elem_t, len) = expr_t { - if len >= *idx { + if len < *idx { return Err(ErrorKind::IndexOutOfBounds(*idx, len)); } Ok(*elem_t) @@ -390,6 +398,12 @@ impl Expression { } } ExprKind::Array(expressions) => { + // Try to unwrap hint type from array if possible + let hint_t = hint_t.map(|t| match t { + Array(type_kind, _) => &type_kind, + _ => t, + }); + let mut expr_result = try_all( expressions .iter_mut() @@ -403,7 +417,7 @@ impl Expression { for other in iter { state.ok(first.collapse_into(other), self.1); } - Ok(first.clone()) + Ok(Array(Box::new(first.clone()), expressions.len() as u64)) } else { Ok(Array(Box::new(Void), 0)) } @@ -479,9 +493,13 @@ impl TypeKind { } fn resolve_hinted(&self, hints: &TypeRefs) -> TypeKind { - match self { + let resolved = match self { Vague(TypeRef(idx)) => hints.retrieve_type(*idx).unwrap(), _ => self.clone(), + }; + match resolved { + Array(t, len) => Array(Box::new(t.resolve_hinted(hints)), len), + _ => resolved, } } } diff --git a/reid/src/mir/typerefs.rs b/reid/src/mir/typerefs.rs index cbcd043..3cf63f0 100644 --- a/reid/src/mir/typerefs.rs +++ b/reid/src/mir/typerefs.rs @@ -4,6 +4,8 @@ use std::{ rc::Rc, }; +use crate::mir::VagueType; + use super::{ typecheck::{Collapsable, ErrorKind}, BinaryOperator, TypeKind, @@ -15,12 +17,22 @@ pub struct TypeRef<'scope>(TypeIdRef, &'scope ScopeTypeRefs<'scope>); impl<'scope> TypeRef<'scope> { pub unsafe fn resolve_type(&self) -> TypeKind { unsafe { - self.1 + let resolved = self + .1 .types .hints .borrow() .get_unchecked(*self.0.borrow()) - .clone() + .clone(); + + match resolved { + TypeKind::Array(elem_ty, len) => { + let resolved_elem_ty = self.1.from_type(&elem_ty).unwrap().resolve_type(); + dbg!(&elem_ty, &resolved_elem_ty); + TypeKind::Array(Box::new(resolved_elem_ty), len) + } + _ => resolved, + } } } @@ -96,7 +108,15 @@ impl TypeRefs { pub fn retrieve_type(&self, idx: usize) -> Option { let inner_idx = unsafe { *self.recurse_type_ref(idx).borrow() }; - self.hints.borrow().get(inner_idx).cloned() + self.hints + .borrow() + .get(inner_idx) + .cloned() + .map(|t| match t { + TypeKind::Vague(VagueType::TypeRef(id)) => self.retrieve_type(id), + _ => Some(t), + }) + .flatten() } }