From c3c1d3d276216796394b553ecbe2832897e3deb0 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 11 Apr 2019 14:21:46 +0200 Subject: Handle untyped case differently from the type of Sort Closes #59 --- dhall/src/expr.rs | 7 +- dhall/src/tests.rs | 2 +- dhall/src/traits/static_type.rs | 2 +- dhall/src/typecheck.rs | 171 ++++++++++++++++++++++++---------------- 4 files changed, 107 insertions(+), 75 deletions(-) (limited to 'dhall') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 5ff097b..aa02c28 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -29,11 +29,11 @@ pub struct Resolved(pub(crate) SubExpr); derive_other_traits!(Resolved); #[derive(Debug, Clone, Eq)] -pub struct Typed(pub(crate) SubExpr, pub(crate) Type); +pub struct Typed(pub(crate) SubExpr, pub(crate) Option); derive_other_traits!(Typed); #[derive(Debug, Clone, Eq)] -pub struct Normalized(pub(crate) SubExpr, pub(crate) Type); +pub struct Normalized(pub(crate) SubExpr, pub(crate) Option); derive_other_traits!(Normalized); /// An expression of type `Type` (like `Bool` or `Natural -> Text`, but not `Type`) @@ -47,7 +47,8 @@ pub struct Type(pub(crate) TypeInternal); #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) enum TypeInternal { Expr(Box), - Untyped, + // The type of `Sort` + SuperType, } // Exposed for the macros diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index 23ec1f4..dcded3a 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -119,7 +119,7 @@ pub fn run_test( } TypeInference => { let expr = expr.typecheck()?; - let ty = expr.get_type().as_normalized()?; + let ty = expr.get_type()?.as_normalized()?; assert_eq_display!(ty, &expected); } Normalization => { diff --git a/dhall/src/traits/static_type.rs b/dhall/src/traits/static_type.rs index 6c41e3f..6b0f5c5 100644 --- a/dhall/src/traits/static_type.rs +++ b/dhall/src/traits/static_type.rs @@ -23,7 +23,7 @@ impl StaticType for T { fn get_static_type() -> Type { crate::expr::Normalized( T::get_simple_static_type().into(), - Type::const_type(), + Some(Type::const_type()), ) .into_type() } diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index 2a527fb..0ddb784 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -20,7 +20,7 @@ impl Resolved { } /// Pretends this expression has been typechecked. Use with care. pub fn skip_typecheck(self) -> Typed { - Typed(self.0, UNTYPE) + Typed(self.0, None) } } impl Typed { @@ -30,11 +30,19 @@ impl Typed { fn into_expr(self) -> SubExpr { self.0 } - pub fn get_type(&self) -> &Type { - &self.1 + 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) -> Type { - self.1 + fn get_type_move(self) -> Result> { + self.1.ok_or(TypeError::new( + &Context::new(), + self.0, + TypeMessage::Untyped, + )) } } impl Normalized { @@ -44,8 +52,12 @@ impl Normalized { pub(crate) fn into_expr(self) -> SubExpr { self.0 } - pub fn get_type(&self) -> &Type { - &self.1 + 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))) @@ -64,7 +76,7 @@ impl Type { use TypeInternal::*; match &self.0 { Expr(e) => Ok(e), - Untyped => Err(TypeError::new( + SuperType => Err(TypeError::new( &Context::new(), rc(ExprF::Const(Const::Sort)), TypeMessage::Untyped, @@ -75,7 +87,7 @@ impl Type { use TypeInternal::*; match self.0 { Expr(e) => Ok(*e), - Untyped => Err(TypeError::new( + SuperType => Err(TypeError::new( &Context::new(), rc(ExprF::Const(Const::Sort)), TypeMessage::Untyped, @@ -86,36 +98,42 @@ impl Type { fn unroll_ref(&self) -> Result<&Expr, TypeError> { Ok(self.as_normalized()?.unroll_ref()) } - pub fn get_type(&self) -> &Type { + pub fn get_type(&self) -> Result<&Type, TypeError> { use TypeInternal::*; match &self.0 { Expr(e) => e.get_type(), - Untyped => &UNTYPE, + SuperType => Err(TypeError::new( + &Context::new(), + rc(ExprF::Const(Const::Sort)), + TypeMessage::Untyped, + )), } } fn shift(&self, delta: isize, var: &V