summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2019-04-11 20:45:43 +0200
committerNadrieril2019-04-11 20:45:43 +0200
commitd9a2a77a19e56edd8eb96eba002e39bc7be3bde3 (patch)
treea2cb1badcaad84b94c08ae6643b81a6b8481559a /dhall
parentd17d553a39aa3bffdfc19b7fe4801b85d6bd80f7 (diff)
Thread lifetimes through other newtypes
Closes #55
Diffstat (limited to 'dhall')
-rw-r--r--dhall/src/expr.rs80
-rw-r--r--dhall/src/imports.rs21
-rw-r--r--dhall/src/normalize.rs20
-rw-r--r--dhall/src/traits/deserialize.rs12
-rw-r--r--dhall/src/traits/dynamic_type.rs16
-rw-r--r--dhall/src/traits/static_type.rs45
-rw-r--r--dhall/src/typecheck.rs135
-rw-r--r--dhall/tests/traits.rs2
8 files changed, 175 insertions, 156 deletions
diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs
index e3a2fe5..3987896 100644
--- a/dhall/src/expr.rs
+++ b/dhall/src/expr.rs
@@ -4,25 +4,6 @@ use std::marker::PhantomData;
macro_rules! derive_other_traits {
($ty:ident) => {
- impl std::cmp::PartialEq for $ty {
- fn eq(&self, other: &Self) -> bool {
- self.0 == other.0
- }
- }
-
- impl std::fmt::Display for $ty {
- fn fmt(
- &self,
- f: &mut std::fmt::Formatter,
- ) -> Result<(), std::fmt::Error> {
- self.0.fmt(f)
- }
- }
- };
-}
-
-macro_rules! derive_other_traits_ {
- ($ty:ident) => {
impl<'a> std::cmp::PartialEq for $ty<'a> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
@@ -46,85 +27,96 @@ pub struct Parsed<'a>(
pub(crate) ImportRoot,
pub(crate) PhantomData<&'a ()>,
);
-derive_other_traits_!(Parsed);
+derive_other_traits!(Parsed);
#[derive(Debug, Clone, Eq)]
pub struct Resolved<'a>(
- pub(crate) SubExpr<X, Normalized>,
+ pub(crate) SubExpr<X, Normalized<'static>>,
pub(crate) PhantomData<&'a ()>,
);
-derive_other_traits_!(Resolved);
+derive_other_traits!(Resolved);
#[derive(Debug, Clone, Eq)]
-pub struct Typed(pub(crate) SubExpr<X, Normalized>, pub(crate) Option<Type>);
+pub struct Typed<'a>(
+ pub(crate) SubExpr<X, Normalized<'static>>,
+ pub(crate) Option<Type<'static>>,
+ pub(crate) PhantomData<&'a ()>,
+);
derive_other_traits!(Typed);
#[derive(Debug, Clone, Eq)]
-pub struct Normalized(pub(crate) SubExpr<X, X>, pub(crate) Option<Type>);
+pub struct Normalized<'a>(
+ pub(crate) SubExpr<X, X>,
+ pub(crate) Option<Type<'static>>,
+ pub(crate) PhantomData<&'a ()>,
+);
derive_other_traits!(Normalized);
/// An expression of type `Type` (like `Bool` or `Natural -> Text`, but not `Type`)
#[derive(Debug, Clone, Eq)]
-pub struct SimpleType(pub(crate) SubExpr<X, X>);
+pub struct SimpleType<'a>(
+ pub(crate) SubExpr<X, X>,
+ pub(crate) PhantomData<&'a ()>,
+);
derive_other_traits!(SimpleType);
#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Type(pub(crate) TypeInternal);
+pub struct Type<'a>(pub(crate) TypeInternal<'a>);
#[derive(Debug, Clone, PartialEq, Eq)]
-pub(crate) enum TypeInternal {
- Expr(Box<Normalized>),
+pub(crate) enum TypeInternal<'a> {
+ Expr(Box<Normalized<'a>>),
// The type of `Sort`
SuperType,
}
// Exposed for the macros
#[doc(hidden)]
-impl From<SimpleType> for SubExpr<X, X> {
- fn from(x: SimpleType) -> SubExpr<X, X> {
+impl<'a> From<SimpleType<'a>> for SubExpr<X, X> {
+ fn from(x: SimpleType<'a>) -> SubExpr<X, X> {
x.0
}
}
// Exposed for the macros
#[doc(hidden)]
-impl From<SubExpr<X, X>> for SimpleType {
- fn from(x: SubExpr<X, X>) -> SimpleType {
- SimpleType(x)
+impl<'a> From<SubExpr<X, X>> for SimpleType<'a> {
+ fn from(x: SubExpr<X, X>) -> SimpleType<'a> {
+ SimpleType(x, PhantomData)
}
}
// Exposed for the macros
#[doc(hidden)]
-impl From<Normalized> for Typed {
- fn from(x: Normalized) -> Typed {
- Typed(x.0.absurd(), x.1)
+impl<'a> From<Normalized<'a>> for Typed<'a> {
+ fn from(x: Normalized<'a>) -> Typed<'a> {
+ Typed(x.0.absurd(), x.1, x.2)
}
}
-impl Typed {
- pub(crate) fn as_expr(&self) -> &SubExpr<X, Normalized> {
+impl<'a> Typed<'a> {
+ pub(crate) fn as_expr(&self) -> &SubExpr<X, Normalized<'a>> {
&self.0
}
- pub(crate) fn into_expr(self) -> SubExpr<X, Normalized> {
+ pub(crate) fn into_expr(self) -> SubExpr<X, Normalized<'a>> {
self.0
}
}
-impl Normalized {
+impl<'a> Normalized<'a> {
pub(crate) fn as_expr(&self) -> &SubExpr<X, X> {
&self.0
}
pub(crate) fn into_expr<T>(self) -> SubExpr<X, T> {
self.0.absurd()
}
- pub(crate) fn into_type(self) -> Type {
+ pub(crate) fn into_type(self) -> Type<'a> {
crate::expr::Type(TypeInternal::Expr(Box::new(self)))
}
}
-impl SimpleType {
- pub(crate) fn into_type(self) -> Type {
- Normalized(self.0, Some(Type::const_type())).into_type()
+impl<'a> SimpleType<'a> {
+ pub(crate) fn into_type(self) -> Type<'a> {
+ Normalized(self.0, Some(Type::const_type()), PhantomData).into_type()
}
}
diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs
index 6b6e2e7..cc9654a 100644
--- a/dhall/src/imports.rs
+++ b/dhall/src/imports.rs
@@ -22,7 +22,7 @@ pub enum ImportRoot {
fn resolve_import(
import: &Import,
root: &ImportRoot,
-) -> Result<Normalized, ImportError> {
+) -> Result<Normalized<'static>, ImportError> {
use self::ImportRoot::*;
use dhall_core::FilePrefix::*;
use dhall_core::ImportLocation::*;
@@ -45,7 +45,7 @@ fn resolve_import(
}
}
-fn load_import(f: &Path) -> Result<Normalized, Error> {
+fn load_import(f: &Path) -> Result<Normalized<'static>, Error> {
Ok(Parsed::parse_file(f)?.resolve()?.typecheck()?.normalize())
}
@@ -53,14 +53,15 @@ fn resolve_expr<'a>(
Parsed(expr, root, marker): Parsed<'a>,
allow_imports: bool,
) -> Result<Resolved<'a>, ImportError> {
- let resolve = |import: &Import| -> Result<Normalized, ImportError> {
- if allow_imports {
- let expr = resolve_import(import, &root)?;
- Ok(expr)
- } else {
- Err(ImportError::UnexpectedImport(import.clone()))
- }
- };
+ let resolve =
+ |import: &Import| -> Result<Normalized<'static>, ImportError> {
+ if allow_imports {
+ let expr = resolve_import(import, &root)?;
+ Ok(expr)
+ } else {
+ Err(ImportError::UnexpectedImport(import.clone()))
+ }
+ };
let expr = expr.as_ref().traverse_embed(&resolve)?;
Ok(Resolved(rc(expr), marker))
}
diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index 1adc0f8..d6c3805 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -4,13 +4,17 @@ use dhall_core::*;
use dhall_generator::dhall_expr;
use std::fmt;
-impl Typed {
- pub fn normalize(self) -> Normalized {
- Normalized(normalize(self.0), self.1)
+impl<'a> Typed<'a> {
+ pub fn normalize(self) -> Normalized<'a> {
+ Normalized(normalize(self.0), self.1, self.2)
}
/// Pretends this expression is normalized. Use with care.
- pub fn skip_normalize(self) -> Normalized {
- Normalized(self.0.unroll().squash_embed(&|e| e.0.clone()), self.1)
+ pub fn skip_normalize(self) -> Normalized<'a> {
+ Normalized(
+ self.0.unroll().squash_embed(&|e| e.0.clone()),
+ self.1,
+ self.2,
+ )
}
}
@@ -221,11 +225,11 @@ enum WhatNext<'a, S, A> {
DoneAsIs,
}
-fn normalize_ref(expr: &Expr<X, Normalized>) -> Expr<X, X> {
+fn normalize_ref(expr: &Expr<X, Normalized<'static>>) -> Expr<X, X> {
use dhall_core::BinOp::*;
use dhall_core::ExprF::*;
// Recursively normalize all subexpressions
- let expr: ExprF<Expr<X, X>, Label, X, Normalized> =
+ let expr: ExprF<Expr<X, X>, Label, X, Normalized<'static>> =
expr.map_ref_simple(|e| normalize_ref(e.as_ref()));
use WhatNext::*;
@@ -327,7 +331,7 @@ fn normalize_ref(expr: &Expr<X, Normalized>) -> Expr<X, X> {
/// However, `normalize` will not fail if the expression is ill-typed and will
/// leave ill-typed sub-expressions unevaluated.
///
-fn normalize(e: SubExpr<X, Normalized>) -> SubExpr<X, X> {
+fn normalize(e: SubExpr<X, Normalized<'static>>) -> SubExpr<X, X> {
normalize_ref(e.as_ref()).roll()
}
diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs
index 3e8cc5e..f1be054 100644
--- a/dhall/src/traits/deserialize.rs
+++ b/dhall/src/traits/deserialize.rs
@@ -21,9 +21,9 @@ impl<'de: 'a, 'a> Deserialize<'de> for Resolved<'a> {
}
}
-impl<'a> Deserialize<'a> for Typed {
+impl<'de: 'a, 'a> Deserialize<'de> for Typed<'a> {
/// Parses, resolves and typechecks the provided string.
- fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> {
+ fn from_str(s: &'de str, ty: Option<&Type>) -> Result<Self> {
let resolved = Resolved::from_str(s, ty)?;
match ty {
None => Ok(resolved.typecheck()?),
@@ -32,15 +32,15 @@ impl<'a> Deserialize<'a> for Typed {
}
}
-impl<'a> Deserialize<'a> for Normalized {
+impl<'de: 'a, 'a> Deserialize<'de> for Normalized<'a> {
/// Parses, resolves, typechecks and normalizes the provided string.
- fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> {
+ fn from_str(s: &'de str, ty: Option<&Type>) -> Result<Self> {
Ok(Typed::from_str(s, ty)?.normalize())
}
}
-impl<'a> Deserialize<'a> for Type {
- fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> {
+impl<'de: 'a, 'a> Deserialize<'de> for Type<'a> {
+ fn from_str(s: &'de str, ty: Option<&Type>) -> Result<Self> {
Ok(Normalized::from_str(s, ty)?.into_type())
}
}
diff --git a/dhall/src/traits/dynamic_type.rs b/dhall/src/traits/dynamic_type.rs
index d03f8cd..28ed76d 100644
--- a/dhall/src/traits/dynamic_type.rs
+++ b/dhall/src/traits/dynamic_type.rs
@@ -6,17 +6,17 @@ use dhall_core::{Const, ExprF};
use std::borrow::Cow;
pub trait DynamicType {
- fn get_type<'a>(&'a self) -> Result<Cow<'a, Type>, TypeError>;
+ fn get_type<'a>(&'a self) -> Result<Cow<'a, Type<'static>>, TypeError>;
}
impl<T: StaticType> DynamicType for T {
- fn get_type<'a>(&'a self) -> Result<Cow<'a, Type>, TypeError> {
+ fn get_type<'a>(&'a self) -> Result<Cow<'a, Type<'static>>, TypeError> {
Ok(Cow::Owned(T::get_static_type()))
}
}
-impl DynamicType for Type {
- fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
+impl<'a> DynamicType for Type<'a> {
+ fn get_type(&self) -> Result<Cow<'_, Type<'static>>, TypeError> {
use TypeInternal::*;
match &self.0 {
Expr(e) => e.get_type(),
@@ -29,8 +29,8 @@ impl DynamicType for Type {
}
}
-impl DynamicType for Normalized {
- fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
+impl<'a> DynamicType for Normalized<'a> {
+ fn get_type(&self) -> Result<Cow<'_, Type<'static>>, TypeError> {
match &self.1 {
Some(t) => Ok(Cow::Borrowed(t)),
None => Err(TypeError::new(
@@ -42,8 +42,8 @@ impl DynamicType for Normalized {
}
}
-impl DynamicType for Typed {
- fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
+impl<'a> DynamicType for Typed<'a> {
+ fn get_type(&self) -> Result<Cow<'_, Type<'static>>, TypeError> {
match &self.1 {
Some(t) => Ok(Cow::Borrowed(t)),
None => Err(TypeError::new(
diff --git a/dhall/src/traits/static_type.rs b/dhall/src/traits/static_type.rs
index 6b0f5c5..35d91e1 100644
--- a/dhall/src/traits/static_type.rs
+++ b/dhall/src/traits/static_type.rs
@@ -3,7 +3,7 @@ use dhall_core::*;
use dhall_generator::*;
pub trait StaticType {
- fn get_static_type() -> Type;
+ fn get_static_type() -> Type<'static>;
}
/// Trait for rust types that can be represented in dhall in
@@ -12,79 +12,80 @@ pub trait StaticType {
/// is `HashMap<Text, bool>` because dhall cannot represent records with a
/// variable number of fields.
pub trait SimpleStaticType {
- fn get_simple_static_type() -> SimpleType;
+ fn get_simple_static_type<'a>() -> SimpleType<'a>;
}
-fn mktype(x: SubExpr<X, X>) -> SimpleType {
- SimpleType(x)
+fn mktype<'a>(x: SubExpr<X, X>) -> SimpleType<'a> {
+ SimpleType(x, std::marker::PhantomData)
}
impl<T: SimpleStaticType> StaticType for T {
- fn get_static_type() -> Type {
+ fn get_static_type() -> Type<'static> {
crate::expr::Normalized(
T::get_simple_static_type().into(),
Some(Type::const_type()),
+ std::marker::PhantomData,
)
.into_type()
}
}
-impl StaticType for SimpleType {
- fn get_static_type() -> Type {
+impl<'a> StaticType for SimpleType<'a> {
+ fn get_static_type() -> Type<'static> {
Type::const_type()
}
}
impl SimpleStaticType for bool {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Bool))
}
}
impl SimpleStaticType for Natural {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Natural))
}
}
impl SimpleStaticType for u32 {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Natural))
}
}
impl SimpleStaticType for u64 {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Natural))
}
}
impl SimpleStaticType for Integer {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Integer))
}
}
impl SimpleStaticType for i32 {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Integer))
}
}
impl SimpleStaticType for i64 {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Integer))
}
}
impl SimpleStaticType for String {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!(Text))
}
}
impl<A: SimpleStaticType, B: SimpleStaticType> SimpleStaticType for (A, B) {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
let ta: SubExpr<_, _> = A::get_simple_static_type().into();
let tb: SubExpr<_, _> = B::get_simple_static_type().into();
mktype(dhall_expr!({ _1: ta, _2: tb }))
@@ -92,27 +93,27 @@ impl<A: SimpleStaticType, B: SimpleStaticType> SimpleStaticType for (A, B) {
}
impl<T: SimpleStaticType> SimpleStaticType for Option<T> {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
let t: SubExpr<_, _> = T::get_simple_static_type().into();
mktype(dhall_expr!(Optional t))
}
}
impl<T: SimpleStaticType> SimpleStaticType for Vec<T> {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
let t: SubExpr<_, _> = T::get_simple_static_type().into();
mktype(dhall_expr!(List t))
}
}
-impl<'a, T: SimpleStaticType> SimpleStaticType for &'a T {
- fn get_simple_static_type() -> SimpleType {
+impl<'b, T: SimpleStaticType> SimpleStaticType for &'b T {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
T::get_simple_static_type()
}
}
impl<T> SimpleStaticType for std::marker::PhantomData<T> {
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
mktype(dhall_expr!({}))
}
}
@@ -120,7 +121,7 @@ impl<T> SimpleStaticType for std::marker::PhantomData<T> {
impl<T: SimpleStaticType, E: SimpleStaticType> SimpleStaticType
for std::result::Result<T, E>
{
- fn get_simple_static_type() -> SimpleType {
+ fn get_simple_static_type<'a>() -> SimpleType<'a> {
let tt: SubExpr<_, _> = T::get_simple_static_type().into();
let te: SubExpr<_, _> = E::get_simple_static_type().into();
mktype(dhall_expr!(< Ok: tt | Err: te>))
diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs
index 41c1b69..d98095c 100644
--- a/dhall/src/typecheck.rs
+++ b/dhall/src/typecheck.rs
@@ -1,6 +1,7 @@
#![allow(non_snake_case)]
use std::borrow::Borrow;
use std::fmt;
+use std::marker::PhantomData;
use crate::expr::*;
use crate::traits::DynamicType;
@@ -12,21 +13,24 @@ use dhall_generator as dhall;
use self::TypeMessage::*;
impl<'a> Resolved<'a> {
- pub fn typecheck(self) -> Result<Typed, TypeError> {
+ pub fn typecheck(self) -> Result<Typed<'static>, TypeError> {
type_of(self.0.clone())
}
- pub fn typecheck_with(self, ty: &Type) -> Result<Typed, TypeError> {
+ pub fn typecheck_with(
+ self,
+ ty: &Type,
+ ) -> Result<Typed<'static>, TypeError> {
let expr: SubExpr<_, _> = self.0.clone();
let ty: SubExpr<_, _> = ty.as_normalized()?.as_expr().absurd();
type_of(dhall::subexpr!(expr: ty))
}
/// Pretends this expression has been typechecked. Use with care.
- pub fn skip_typecheck(self) -> Typed {
- Typed(self.0, None)
+ pub fn skip_typecheck(self) -> Typed<'a> {
+ Typed(self.0, None, self.1)
}
}
-impl Typed {
- fn get_type_move(self) -> Result<Type, TypeError> {
+impl<'a> Typed<'a> {
+ fn get_type_move(self) -> Result<Type<'static>, TypeError> {
self.1.ok_or(TypeError::new(
&Context::new(),
self.0,
@@ -34,18 +38,18 @@ impl Typed {
))
}
}
-impl Normalized {
+impl<'a> Normalized<'a> {
// Expose the outermost constructor
fn unroll_ref(&self) -> &Expr<X, X> {
self.as_expr().as_ref()
}
fn shift(&self, delta: isize, var: &V<Label>) -> Self {
// shift the type too ?
- Normalized(shift(delta, var, &self.0), self.1.clone())
+ Normalized(shift(delta, var, &self.0), self.1.clone(), self.2)
}
}
-impl Type {
- pub fn as_normalized(&self) -> Result<&Normalized, TypeError> {
+impl<'a> Type<'a> {
+ pub fn as_normalized(&self) -> Result<&Normalized<'a>, TypeError> {
use TypeInternal::*;
match &self.0 {
Expr(e) => Ok(e),
@@ -56,7 +60,7 @@ impl Type {
)),
}
}
- pub(crate) fn into_normalized(self) -> Result<Normalized, TypeError> {
+ pub(crate) fn into_normalized(self) -> Result<Normalized<'a>, TypeError> {
use TypeInternal::*;
match self.0 {
Expr(e) => Ok(*e),
@@ -83,16 +87,25 @@ impl Type {
Normalized(
rc(ExprF::Const(Const::Sort)),
Some(Type(TypeInternal::SuperType)),
+ PhantomData,
)
.into_type()
}
pub fn const_kind() -> Self {
- Normalized(rc(ExprF::Const(Const::Kind)), Some(Type::const_sort()))
- .into_type()
+ Normalized(
+ rc(ExprF::Const(Const::Kind)),
+ Some(Type::const_sort()),
+ PhantomData,
+ )
+ .into_type()
}
pub fn const_type() -> Self {
- Normalized(rc(ExprF::Const(Const::Type)), Some(Type::const_kind()))
- .into_type()
+ Normalized(
+ rc(ExprF::Const(Const::Type)),
+ Some(Type::const_kind()),
+ PhantomData,
+ )
+ .into_type()
}
}
@@ -129,8 +142,8 @@ fn match_vars(vl: &V<Label>, vr: &V<Label>, ctx: &[(Label, Label)]) -> bool {
// Equality up to alpha-equivalence (renaming of bound variables)
fn prop_equal<T, U>(eL0: T, eR0: U) -> bool
where
- T: Borrow<Type>,
- U: Borrow<Type>,
+ T: Borrow<Type<'static>>,
+ U: Borrow<Type<'static>>,
{
use dhall_core::ExprF::*;
fn go<S, T>(
@@ -197,7 +210,7 @@ where
}
}
-fn type_of_builtin<S>(b: Builtin) -> Expr<S, Normalized> {
+fn type_of_builtin<S>(b: Builtin) -> Expr<S, Normalized<'static>> {
use dhall_core::Builtin::*;
match b {
Bool | Natural | Integer | Double | Text => dhall::expr!(Type),
@@ -294,23 +307,24 @@ macro_rules! ensure_is_const {
/// Type-check an expression and return the expression alongside its type
/// if type-checking succeeded, or an error if type-checking failed
pub fn type_with(
- ctx: &Context<Label, Type>,
- e: SubExpr<X, Normalized>,
-) -> Result<Typed, TypeError> {
+ ctx: &Context<Label, Type<'static>>,
+ e: SubExpr<X, Normalized<'static>>,
+) -> Result<Typed<'static>, TypeError> {
use dhall_core::BinOp::*;
use dhall_core::Const::*;
use dhall_core::ExprF::*;
- let mkerr = |msg: TypeMessage| TypeError::new(ctx, e.clone(), msg);
+ let mkerr = |msg: TypeMessage<'static>| TypeError::new(ctx, e.clone(), msg);
- let mktype = |ctx, x: SubExpr<X, Normalized>| {
+ let mktype = |ctx, x: SubExpr<X, Normalized<'static>>| {
Ok(type_with(ctx, x)?.normalize().into_type())
};
- let mksimpletype = |x: SubExpr<X, X>| SimpleType(x).into_type();
+ let mksimpletype =
+ |x: SubExpr<X, X>| SimpleType(x, PhantomData).into_type();
enum Ret {
- RetType(crate::expr::Type),
- RetExpr(Expr<X, Normalized>),
+ RetType(crate::expr::Type<'static>),
+ RetExpr(Expr<X, Normalized<'static>>),
}
use Ret::*;
let ret = match e.as_ref() {
@@ -418,6 +432,7 @@ pub fn type_with(
mkerr(NotAFunction(Typed(
rc(App(f.into_expr(), seen_args)),
Some(tf),
+ PhantomData
)))
);
let tx = mktype(ctx, tx.absurd())?;
@@ -425,7 +440,11 @@ pub fn type_with(
&tx,
a.get_type()?,
mkerr(TypeMismatch(
- Typed(rc(App(f.into_expr(), seen_args)), Some(tf)),
+ Typed(
+ rc(App(f.into_expr(), seen_args)),
+ Some(tf),
+ PhantomData
+ ),
tx.into_normalized()?,
a,
))
@@ -592,15 +611,17 @@ pub fn type_with(
},
}?;
match ret {
- RetExpr(ret) => Ok(Typed(e, Some(mktype(ctx, rc(ret))?))),
- RetType(typ) => Ok(Typed(e, Some(typ))),
+ RetExpr(ret) => Ok(Typed(e, Some(mktype(ctx, rc(ret))?), PhantomData)),
+ RetType(typ) => Ok(Typed(e, Some(typ), PhantomData)),
}
}
/// `typeOf` is the same as `type_with` with an empty context, meaning that the
/// expression must be closed (i.e. no free variables), otherwise type-checking
/// will fail.
-pub fn type_of(e: SubExpr<X, Normalized>) -> Result<Typed, TypeError> {
+pub fn type_of(
+ e: SubExpr<X, Normalized<'static>>,
+) -> Result<Typed<'static>, TypeError> {
let ctx = Context::new();
let e = type_with(&ctx, e)?;
// Ensure the inferred type isn't SuperType
@@ -610,45 +631,45 @@ pub fn type_of(e: SubExpr<X, Normalized>) -> Result<Typed, TypeError> {
/// The specific type error
#[derive(Debug)]
-pub enum TypeMessage {
+pub enum TypeMessage<'a> {
UnboundVariable,
- InvalidInputType(Normalized),
- InvalidOutputType(Normalized),
- NotAFunction(Typed),
- TypeMismatch(Typed, Normalized, Typed),
- AnnotMismatch(Typed, Normalized),
+ InvalidInputType(Normalized<'a>),
+ InvalidOutputType(Normalized<'a>),
+ NotAFunction(Typed<'a>),
+ TypeMismatch(Typed<'a>, Normalized<'a>, Typed<'a>),
+ AnnotMismatch(Typed<'a>, Normalized<'a>),
Untyped,
- InvalidListElement(usize, Normalized, Typed),
- InvalidListType(Normalized),
- InvalidOptionalType(Normalized),
- InvalidPredicate(Typed),
- IfBranchMismatch(Typed, Typed),
- IfBranchMustBeTerm(bool, Typed),
- InvalidField(Label, Typed),
- InvalidFieldType(Label, Typed),
+ InvalidListElement(usize, Normalized<'a>, Typed<'a>),
+ InvalidListType(Normalized<'a>),
+ InvalidOptionalType(Normalized<'a>),
+ InvalidPredicate(Typed<'a>),
+ IfBranchMismatch(Typed<'a>, Typed<'a>),
+ IfBranchMustBeTerm(bool, Typed<'a>),
+ InvalidField(Label, Typed<'a>),
+ InvalidFieldType(Label, Typed<'a>),
DuplicateAlternative(Label),
FieldCollision(Label),
- NotARecord(Label, Typed),
- MissingField(Label, Typed),
- BinOpTypeMismatch(BinOp, Typed),
- NoDependentLet(Normalized, Normalized),
- NoDependentTypes(Normalized, Normalized),
+ NotARecord(Label, Typed<'a>),
+ MissingField(Label, Typed<'a>),
+ BinOpTypeMismatch(BinOp, Typed<'a>),
+ NoDependentLet(Normalized<'a>, Normalized<'a>),
+ NoDependentTypes(Normalized<'a>, Normalized<'a>),
Unimplemented,
}
/// A structured type error that includes context
#[derive(Debug)]
pub struct TypeError {
- pub context: Context<Label, Type>,
- pub current: SubExpr<X, Normalized>,
- pub type_message: TypeMessage,
+ pub context: Context<Label, Type<'static>>,
+ pub current: SubExpr<X, Normalized<'static>>,
+ pub type_message: TypeMessage<'static>,
}
impl TypeError {
pub fn new(
- context: &Context<Label, Type>,
- current: SubExpr<X, Normalized>,
- type_message: TypeMessage,
+ context: &Context<Label, Type<'static>>,
+ current: SubExpr<X, Normalized<'static>>,
+ type_message: TypeMessage<'static>,
) -> Self {
TypeError {
context: context.clone(),
@@ -658,7 +679,7 @@ impl TypeError {
}
}
-impl ::std::error::Error for TypeMessage {
+impl ::std::error::Error for TypeMessage<'static> {
fn description(&self) -> &str {
match *self {
UnboundVariable => "Unbound variable",
@@ -671,7 +692,7 @@ impl ::std::error::Error for TypeMessage {
}
}
-impl fmt::Display for TypeMessage {
+impl fmt::Display for TypeMessage<'static> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
UnboundVariable => {
diff --git a/dhall/tests/traits.rs b/dhall/tests/traits.rs
index 1e9b3c2..ef3e385 100644
--- a/dhall/tests/traits.rs
+++ b/dhall/tests/traits.rs
@@ -5,7 +5,7 @@ use dhall_generator::dhall_expr;
#[test]
fn test_static_type() {
- fn mktype(x: SubExpr<X, X>) -> dhall::expr::SimpleType {
+ fn mktype(x: SubExpr<X, X>) -> dhall::expr::SimpleType<'static> {
x.into()
}