From 36a6f9a09b966922baf4838599e57250982b0fc3 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 11 Apr 2019 15:15:20 +0200 Subject: Abstract get_type() into a trait --- dhall/src/expr.rs | 22 ++++++++++++++++ dhall/src/lib.rs | 6 ++--- dhall/src/tests.rs | 5 ++-- dhall/src/traits/dynamic_type.rs | 56 ++++++++++++++++++++++++++++++++++++++++ dhall/src/traits/mod.rs | 2 ++ dhall/src/typecheck.rs | 54 +++++++------------------------------- 6 files changed, 96 insertions(+), 49 deletions(-) create mode 100644 dhall/src/traits/dynamic_type.rs (limited to 'dhall') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index aa02c28..6458be9 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -66,3 +66,25 @@ impl From> for SimpleType { SimpleType(x) } } + +impl Typed { + pub(crate) fn as_expr(&self) -> &SubExpr { + &self.0 + } + pub(crate) fn into_expr(self) -> SubExpr { + self.0 + } +} + +impl Normalized { + pub(crate) fn as_expr(&self) -> &SubExpr { + &self.0 + } + pub(crate) fn into_expr(self) -> SubExpr { + self.0 + } + pub(crate) fn into_type(self) -> Type { + crate::expr::Type(TypeInternal::Expr(Box::new(self))) + } +} + diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 8af5af9..6d08d08 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -126,9 +126,9 @@ mod imports; mod normalize; mod traits; mod typecheck; -pub use crate::traits::Deserialize; -pub use crate::traits::SimpleStaticType; -pub use crate::traits::StaticType; +pub use crate::traits::{ + Deserialize, DynamicType, SimpleStaticType, StaticType, +}; pub use dhall_generator::SimpleStaticType; pub mod error; pub mod expr; diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index dcded3a..798f3e9 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -41,6 +41,7 @@ macro_rules! make_spec_test { use crate::error::{Error, Result}; use crate::expr::Parsed; +use crate::DynamicType; use std::path::PathBuf; #[derive(Copy, Clone)] @@ -119,8 +120,8 @@ pub fn run_test( } TypeInference => { let expr = expr.typecheck()?; - let ty = expr.get_type()?.as_normalized()?; - assert_eq_display!(ty, &expected); + let ty = expr.get_type()?; + assert_eq_display!(ty.as_normalized()?, &expected); } Normalization => { let expr = expr.skip_typecheck().normalize(); diff --git a/dhall/src/traits/dynamic_type.rs b/dhall/src/traits/dynamic_type.rs new file mode 100644 index 0000000..25fe52d --- /dev/null +++ b/dhall/src/traits/dynamic_type.rs @@ -0,0 +1,56 @@ +use crate::expr::*; +use crate::traits::StaticType; +use crate::typecheck::{TypeError, TypeMessage}; +use dhall_core::context::Context; +use dhall_core::{Const, ExprF, X}; +use std::borrow::Cow; + +pub trait DynamicType { + fn get_type<'a>(&'a self) -> Result, TypeError>; +} + +impl DynamicType for T { + fn get_type<'a>(&'a self) -> Result, TypeError> { + Ok(Cow::Owned(T::get_static_type())) + } +} + +impl DynamicType for Type { + fn get_type(&self) -> Result, TypeError> { + use TypeInternal::*; + match &self.0 { + Expr(e) => e.get_type(), + SuperType => Err(TypeError::new( + &Context::new(), + dhall_core::rc(ExprF::Const(Const::Sort)), + TypeMessage::Untyped, + )), + } + } +} + +impl DynamicType for Normalized { + fn get_type(&self) -> Result, TypeError> { + match &self.1 { + Some(t) => Ok(Cow::Borrowed(t)), + None => Err(TypeError::new( + &Context::new(), + self.0.clone(), + TypeMessage::Untyped, + )), + } + } +} + +impl DynamicType for Typed { + fn get_type(&self) -> Result, TypeError> { + match &self.1 { + Some(t) => Ok(Cow::Borrowed(t)), + None => Err(TypeError::new( + &Context::new(), + self.0.clone(), + TypeMessage::Untyped, + )), + } + } +} diff --git a/dhall/src/traits/mod.rs b/dhall/src/traits/mod.rs index 4ce8f97..315e17a 100644 --- a/dhall/src/traits/mod.rs +++ b/dhall/src/traits/mod.rs @@ -1,4 +1,6 @@ mod deserialize; +mod dynamic_type; mod static_type; pub use deserialize::Deserialize; +pub use dynamic_type::DynamicType; pub use static_type::{SimpleStaticType, StaticType}; diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index 0ddb784..3350964 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -1,7 +1,9 @@ #![allow(non_snake_case)] +use std::borrow::Borrow; use std::fmt; use crate::expr::*; +use crate::traits::DynamicType; use dhall_core; use dhall_core::context::Context; use dhall_core::*; @@ -24,19 +26,6 @@ impl Resolved { } } impl Typed { - fn as_expr(&self) -> &SubExpr { - &self.0 - } - fn into_expr(self) -> SubExpr { - self.0 - } - pub fn get_type(&self) -> Result<&Type, TypeError> { - self.1.as_ref().ok_or(TypeError::new( - &Context::new(), - self.0.clone(), - TypeMessage::Untyped, - )) - } fn get_type_move(self) -> Result> { self.1.ok_or(TypeError::new( &Context::new(), @@ -46,22 +35,6 @@ impl Typed { } } impl Normalized { - fn as_expr(&self) -> &SubExpr { - &self.0 - } - pub(crate) fn into_expr(self) -> SubExpr { - self.0 - } - pub fn get_type(&self) -> Result<&Type, TypeError> { - self.1.as_ref().ok_or(TypeError::new( - &Context::new(), - self.0.clone(), - TypeMessage::Untyped, - )) - } - pub(crate) fn into_type(self) -> Type { - crate::expr::Type(TypeInternal::Expr(Box::new(self))) - } // Expose the outermost constructor fn unroll_ref(&self) -> &Expr { self.as_expr().as_ref() @@ -98,17 +71,6 @@ impl Type { fn unroll_ref(&self) -> Result<&Expr, TypeError> { Ok(self.as_normalized()?.unroll_ref()) } - pub fn get_type(&self) -> Result<&Type, TypeError> { - use TypeInternal::*; - match &self.0 { - Expr(e) => e.get_type(), - SuperType => Err(TypeError::new( - &Context::new(), - rc(ExprF::Const(Const::Sort)), - TypeMessage::Untyped, - )), - } - } fn shift(&self, delta: isize, var: &V