diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-10 15:18:08 +0300 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-10 15:18:08 +0300 |
commit | 2274a96d1cbd7a5b89bb6b5f51f6bbb0a0513587 (patch) | |
tree | b11550b9e80fdf761e91a51aca49ee849589052a /src/type/conversion.rs | |
parent | c121f20620499e9b7c497c82c7321474cbf59e1d (diff) | |
download | myslip-2274a96d1cbd7a5b89bb6b5f51f6bbb0a0513587.tar.gz myslip-2274a96d1cbd7a5b89bb6b5f51f6bbb0a0513587.zip |
Added into_type and used it to implement implicit conversions in type checking
Diffstat (limited to 'src/type/conversion.rs')
-rw-r--r-- | src/type/conversion.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/type/conversion.rs b/src/type/conversion.rs index a819409..3be2874 100644 --- a/src/type/conversion.rs +++ b/src/type/conversion.rs @@ -71,6 +71,60 @@ impl Type { } + /// Tries to convert this type into a subtype of the other. + /// + /// ```rust + /// use myslip::r#type::{Type::*, util::*}; + /// + /// assert_eq!(Integer.into_type(&Boolean), Err(())); + /// assert_eq!(Integer.into_type(&Integer), Ok(Integer)); + /// assert_eq!(Integer.into_type(&vt("T")), Ok(Integer)); + /// assert_eq!( + /// List(vec![Integer, Integer]).into_type(&vecof(Integer)), + /// Ok(vecof(Integer)) + /// ); + /// assert_eq!( + /// List(vec![Integer, Integer]).into_type(&vecof(vt("T"))), + /// Ok(vecof(Integer)) + /// ); + /// assert_eq!( + /// List(vec![Integer, Boolean]).into_type(&vecof(vt("T"))), + /// Ok(vecof(vt("T"))) + /// ); + /// ``` + pub fn into_type(self, other: &Type) -> Result<Type, ()> { + if !self.aka(other) { + return Err(()); + } + + match (&self, other) { + + (a, b) if a == b => Ok(self), + + (_, VarType(_)) => Ok(self), + + (List(v), VecOf(b)) => match v.get(0) { + Some(first) => { + let cand = v.into_iter() + .fold(first.clone(), |a, b| a.least_general_supertype(b)); + if cand.aka(b) { + Ok(vecof(cand)) + } else { + Err(()) + } + }, + None => if NilType.aka(b) { + Ok(vecof(NilType)) + } else { + Err(()) + }, + }, + + _ => Err(()) + + } + } + } #[cfg(test)] |