From 6287b7a7f9e421877ee13fefa586395fec844c99 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 6 Dec 2020 21:41:03 +0000 Subject: Thread cx through typecheck --- dhall/src/semantics/tck/env.rs | 16 ++++++++++++---- dhall/src/semantics/tck/typecheck.rs | 19 ++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) (limited to 'dhall/src/semantics/tck') diff --git a/dhall/src/semantics/tck/env.rs b/dhall/src/semantics/tck/env.rs index 1fa66f0..fc0ce9f 100644 --- a/dhall/src/semantics/tck/env.rs +++ b/dhall/src/semantics/tck/env.rs @@ -1,5 +1,6 @@ use crate::semantics::{AlphaVar, NameEnv, Nir, NzEnv, NzVar, Type, ValEnv}; use crate::syntax::Label; +use crate::Ctxt; /// Environment for indexing variables. #[derive(Debug, Clone, Copy, Default)] @@ -9,7 +10,8 @@ pub struct VarEnv { /// Environment for typing expressions. #[derive(Debug, Clone)] -pub struct TyEnv { +pub struct TyEnv<'cx> { + cx: Ctxt<'cx>, names: NameEnv, items: ValEnv, } @@ -38,13 +40,17 @@ impl VarEnv { } } -impl TyEnv { - pub fn new() -> Self { +impl<'cx> TyEnv<'cx> { + pub fn new(cx: Ctxt<'cx>) -> Self { TyEnv { + cx, names: NameEnv::new(), items: ValEnv::new(), } } + pub fn cx(&self) -> Ctxt<'cx> { + self.cx + } pub fn as_varenv(&self) -> VarEnv { self.names.as_varenv() } @@ -57,12 +63,14 @@ impl TyEnv { pub fn insert_type(&self, x: &Label, ty: Type) -> Self { TyEnv { + cx: self.cx, names: self.names.insert(x), items: self.items.insert_type(ty), } } pub fn insert_value(&self, x: &Label, e: Nir, ty: Type) -> Self { TyEnv { + cx: self.cx, names: self.names.insert(x), items: self.items.insert_value(e, ty), } @@ -72,7 +80,7 @@ impl TyEnv { } } -impl<'a> From<&'a TyEnv> for NzEnv { +impl<'a, 'cx> From<&'a TyEnv<'cx>> for NzEnv { fn from(x: &'a TyEnv) -> Self { x.to_nzenv() } diff --git a/dhall/src/semantics/tck/typecheck.rs b/dhall/src/semantics/tck/typecheck.rs index 498bd76..7e8c0e1 100644 --- a/dhall/src/semantics/tck/typecheck.rs +++ b/dhall/src/semantics/tck/typecheck.rs @@ -5,6 +5,7 @@ use crate::error::{ErrorBuilder, TypeError, TypeMessage}; use crate::operations::typecheck_operation; use crate::semantics::{Hir, HirKind, Nir, NirKind, Tir, TyEnv, Type}; use crate::syntax::{Const, ExprKind, InterpolatedTextContents, NumKind, Span}; +use crate::Ctxt; fn function_check(a: Const, b: Const) -> Const { if b == Const::Type { @@ -29,7 +30,7 @@ pub fn mk_span_err(span: Span, msg: S) -> Result { /// When all sub-expressions have been typed, check the remaining toplevel /// layer. fn type_one_layer( - env: &TyEnv, + env: &TyEnv<'_>, ekind: ExprKind>, span: Span, ) -> Result { @@ -58,7 +59,7 @@ fn type_one_layer( }), ExprKind::Builtin(b) => { let t_hir = type_of_builtin(b); - typecheck(&t_hir)?.eval_to_type(env)? + typecheck(env.cx(), &t_hir)?.eval_to_type(env)? } ExprKind::TextLit(interpolated) => { let text_type = Type::from_builtin(Builtin::Text); @@ -171,7 +172,7 @@ fn type_one_layer( // We pass the annotation to avoid duplicating the annot checking logic. I hope one day we can use // it to handle the annotations in merge/toMap/etc. uniformly. pub fn type_with<'hir>( - env: &TyEnv, + env: &TyEnv<'_>, hir: &'hir Hir, annot: Option, ) -> Result, TypeError> { @@ -267,15 +268,19 @@ pub fn type_with<'hir>( /// Typecheck an expression and return the expression annotated with its type if type-checking /// succeeded, or an error if type-checking failed. -pub fn typecheck<'hir>(hir: &'hir Hir) -> Result, TypeError> { - type_with(&TyEnv::new(), hir, None) +pub fn typecheck<'hir>( + cx: Ctxt<'_>, + hir: &'hir Hir, +) -> Result, TypeError> { + type_with(&TyEnv::new(cx), hir, None) } /// Like `typecheck`, but additionally checks that the expression's type matches the provided type. pub fn typecheck_with<'hir>( + cx: Ctxt<'_>, hir: &'hir Hir, ty: &Hir, ) -> Result, TypeError> { - let ty = typecheck(ty)?.eval_to_type(&TyEnv::new())?; - type_with(&TyEnv::new(), hir, Some(ty)) + let ty = typecheck(cx, ty)?.eval_to_type(&TyEnv::new(cx))?; + type_with(&TyEnv::new(cx), hir, Some(ty)) } -- cgit v1.2.3