diff --git a/reid/src/mir/impl.rs b/reid/src/mir/implement.rs similarity index 84% rename from reid/src/mir/impl.rs rename to reid/src/mir/implement.rs index 503b1c7..889155d 100644 --- a/reid/src/mir/impl.rs +++ b/reid/src/mir/implement.rs @@ -1,4 +1,6 @@ -use super::{typecheck::ErrorKind, typerefs::TypeRefs, VagueType as Vague, *}; +use crate::util::try_all; + +use super::{pass::ScopeFunction, typecheck::ErrorKind, typerefs::TypeRefs, VagueType as Vague, *}; #[derive(Debug, Clone)] pub enum ReturnTypeOther { @@ -350,6 +352,64 @@ impl TypeKind { } } +pub trait Collapsable: Sized + Clone { + /// Try to narrow two types into one singular type. E.g. Vague(Number) and + /// I32 could be narrowed to just I32. + fn collapse_into(&self, other: &Self) -> Result; +} + +impl Collapsable for TypeKind { + fn collapse_into(&self, other: &TypeKind) -> Result { + if self == other { + return Ok(self.clone()); + } + + match (self, other) { + (TypeKind::Vague(Vague::Number), other) | (other, TypeKind::Vague(Vague::Number)) => { + match other { + TypeKind::Vague(Vague::Unknown) => Ok(TypeKind::Vague(Vague::Number)), + TypeKind::Vague(Vague::Number) => Ok(TypeKind::Vague(Vague::Number)), + TypeKind::I8 + | TypeKind::I16 + | TypeKind::I32 + | TypeKind::I64 + | TypeKind::I128 + | TypeKind::U8 + | TypeKind::U16 + | TypeKind::U32 + | TypeKind::U64 + | TypeKind::U128 => Ok(other.clone()), + _ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())), + } + } + (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, + )), + _ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())), + } + } +} + +impl Collapsable for ScopeFunction { + fn collapse_into(&self, other: &ScopeFunction) -> Result { + Ok(ScopeFunction { + ret: self.ret.collapse_into(&other.ret)?, + params: try_all( + self.params + .iter() + .zip(&other.params) + .map(|(p1, p2)| p1.collapse_into(&p2)) + .collect(), + ) + .map_err(|e| e.first().unwrap().clone())?, + }) + } +} + #[derive(Debug, Clone, thiserror::Error, PartialEq, Eq, PartialOrd, Ord)] pub enum EqualsIssue { #[error("Function is already defined locally at {:?}", (.0).range)] diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index e8b66af..0dcd38d 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -16,8 +16,8 @@ use crate::{ }; use super::{ + implement::EqualsIssue, pass::{Pass, PassResult, PassState}, - r#impl::EqualsIssue, Context, FunctionDefinition, Import, Metadata, Module, }; diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 8ef140c..e0bdb5c 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -10,7 +10,7 @@ use crate::{ }; mod fmt; -pub mod r#impl; +pub mod implement; pub mod linker; pub mod pass; pub mod typecheck; diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 77e83fb..2a1cb25 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -6,7 +6,8 @@ use crate::{mir::*, util::try_all}; use VagueType as Vague; use super::{ - pass::{Pass, PassResult, PassState, ScopeFunction, ScopeVariable}, + implement::Collapsable, + pass::{Pass, PassResult, PassState, ScopeVariable}, typerefs::TypeRefs, }; @@ -725,63 +726,3 @@ impl Literal { } } } - -impl TypeKind {} - -pub trait Collapsable: Sized + Clone { - /// Try to narrow two types into one singular type. E.g. Vague(Number) and - /// I32 could be narrowed to just I32. - fn collapse_into(&self, other: &Self) -> Result; -} - -impl Collapsable for TypeKind { - fn collapse_into(&self, other: &TypeKind) -> Result { - if self == other { - return Ok(self.clone()); - } - - match (self, other) { - (TypeKind::Vague(Vague::Number), other) | (other, TypeKind::Vague(Vague::Number)) => { - match other { - TypeKind::Vague(Vague::Unknown) => Ok(TypeKind::Vague(Vague::Number)), - TypeKind::Vague(Vague::Number) => Ok(TypeKind::Vague(Vague::Number)), - TypeKind::I8 - | TypeKind::I16 - | TypeKind::I32 - | TypeKind::I64 - | TypeKind::I128 - | TypeKind::U8 - | TypeKind::U16 - | TypeKind::U32 - | TypeKind::U64 - | TypeKind::U128 => Ok(other.clone()), - _ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())), - } - } - (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, - )), - _ => Err(ErrorKind::TypesIncompatible(self.clone(), other.clone())), - } - } -} - -impl Collapsable for ScopeFunction { - fn collapse_into(&self, other: &ScopeFunction) -> Result { - Ok(ScopeFunction { - ret: self.ret.collapse_into(&other.ret)?, - params: try_all( - self.params - .iter() - .zip(&other.params) - .map(|(p1, p2)| p1.collapse_into(&p2)) - .collect(), - ) - .map_err(|e| e.first().unwrap().clone())?, - }) - } -} diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index f00c38a..4215a55 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -9,8 +9,8 @@ use std::{convert::Infallible, iter}; use crate::{mir::TypeKind, util::try_all}; use super::{ + implement::pick_return, pass::{Pass, PassResult, PassState}, - r#impl::pick_return, typecheck::ErrorKind, typerefs::{ScopeTypeRefs, TypeRef, TypeRefs}, Block, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind, IfExpression, Module, diff --git a/reid/src/mir/typerefs.rs b/reid/src/mir/typerefs.rs index 885c953..729c87c 100644 --- a/reid/src/mir/typerefs.rs +++ b/reid/src/mir/typerefs.rs @@ -6,10 +6,7 @@ use std::{ use crate::mir::VagueType; -use super::{ - typecheck::{Collapsable, ErrorKind}, - BinaryOperator, TypeKind, -}; +use super::{implement::Collapsable, typecheck::ErrorKind, BinaryOperator, TypeKind}; #[derive(Clone)] pub struct TypeRef<'scope>(TypeIdRef, &'scope ScopeTypeRefs<'scope>);