summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2019-03-31 18:47:34 +0200
committerNadrieril2019-03-31 18:47:34 +0200
commitf5d2151d35942b957230c3081a928af3619d9400 (patch)
treea7d2568153d2086a9fd5292585636a26bc914f83 /dhall
parentbc64e9e305f50ad04e6e2071dad8c153c1582b8c (diff)
Make SubExpr a newtype
Diffstat (limited to 'dhall')
-rw-r--r--dhall/src/binary.rs3
-rw-r--r--dhall/src/main.rs3
-rw-r--r--dhall/src/normalize.rs39
-rw-r--r--dhall/src/typecheck.rs103
4 files changed, 70 insertions, 78 deletions
diff --git a/dhall/src/binary.rs b/dhall/src/binary.rs
index 235a55b..988891b 100644
--- a/dhall/src/binary.rs
+++ b/dhall/src/binary.rs
@@ -1,9 +1,8 @@
use dhall_core::*;
use itertools::*;
use serde_cbor::value::value as cbor;
-use std::rc::Rc;
-type ParsedExpr = Rc<Expr<X, Import>>;
+type ParsedExpr = SubExpr<X, Import>;
#[derive(Debug)]
pub enum DecodeError {
diff --git a/dhall/src/main.rs b/dhall/src/main.rs
index 1a2e309..eb2206b 100644
--- a/dhall/src/main.rs
+++ b/dhall/src/main.rs
@@ -1,6 +1,5 @@
use std::error::Error;
use std::io::{self, Read};
-use std::rc::Rc;
use term_painter::ToStyle;
use dhall::*;
@@ -66,7 +65,7 @@ fn main() {
}
};
- let expr: Rc<Expr<_, _>> = rc(imports::panic_imports(&expr));
+ let expr: SubExpr<_, _> = rc(imports::panic_imports(&expr));
let type_expr = match typecheck::type_of(expr.clone()) {
Err(e) => {
diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index a3a2318..5405e88 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -2,7 +2,6 @@
use dhall_core::*;
use dhall_generator::dhall_expr;
use std::fmt;
-use std::rc::Rc;
fn apply_builtin<S, A>(
b: Builtin,
@@ -44,13 +43,13 @@ where
}
// Normalize the important argument
if let Some(i) = arg_to_eval {
- args[i] = Rc::clone(&normalize_whnf(&args[i]));
+ args[i] = SubExpr::clone(&normalize_whnf(&args[i]));
}
let evaled_arg = arg_to_eval.map(|i| args[i].as_ref());
let ret = match (b, evaled_arg, args.as_slice()) {
- (OptionalSome, _, [x, ..]) => rc(NEOptionalLit(Rc::clone(x))),
- (OptionalNone, _, [t, ..]) => rc(EmptyOptionalLit(Rc::clone(t))),
+ (OptionalSome, _, [x, ..]) => rc(NEOptionalLit(SubExpr::clone(x))),
+ (OptionalNone, _, [t, ..]) => rc(EmptyOptionalLit(SubExpr::clone(t))),
(NaturalIsZero, Some(NaturalLit(n)), _) => rc(BoolLit(*n == 0)),
(NaturalEven, Some(NaturalLit(n)), _) => rc(BoolLit(*n % 2 == 0)),
(NaturalOdd, Some(NaturalLit(n)), _) => rc(BoolLit(*n % 2 != 0)),
@@ -76,7 +75,7 @@ where
rc(NEListLit(ys))
}
(ListIndexed, Some(EmptyListLit(t)), _) => {
- let t = Rc::clone(t);
+ let t = SubExpr::clone(t);
dhall_expr!([] : List ({ index : Natural, value : t }))
}
(ListIndexed, Some(NEListLit(xs)), _) => {
@@ -101,7 +100,7 @@ where
break rc(App(x.clone(), rest.to_vec()));
}
};
- let a0 = Rc::clone(a0);
+ let a0 = SubExpr::clone(a0);
let a1 = shift(1, &V("a".into(), 0), &a0);
// TODO: use Embed to avoid reevaluating g
break dhall_expr!(
@@ -122,7 +121,7 @@ where
break rc(App(x.clone(), rest.to_vec()));
}
};
- let a0 = Rc::clone(a0);
+ let a0 = SubExpr::clone(a0);
// TODO: use Embed to avoid reevaluating g
break dhall_expr!(
g
@@ -133,13 +132,13 @@ where
}
}
(ListFold, Some(EmptyListLit(_)), [_, _, _, _, nil, ..]) => {
- Rc::clone(nil)
+ SubExpr::clone(nil)
}
(ListFold, Some(NEListLit(xs)), [_, _, _, cons, nil, ..]) => {
- xs.iter().rev().fold(Rc::clone(nil), |acc, x| {
+ xs.iter().rev().fold(SubExpr::clone(nil), |acc, x| {
let x = x.clone();
let acc = acc.clone();
- let cons = Rc::clone(cons);
+ let cons = SubExpr::clone(cons);
dhall_expr!(cons x acc)
})
}
@@ -149,14 +148,14 @@ where
// }
(OptionalFold, Some(NEOptionalLit(x)), [_, _, _, just, _, ..]) => {
let x = x.clone();
- let just = Rc::clone(just);
+ let just = SubExpr::clone(just);
dhall_expr!(just x)
}
(
OptionalFold,
Some(EmptyOptionalLit(_)),
[_, _, _, _, nothing, ..],
- ) => Rc::clone(nothing),
+ ) => SubExpr::clone(nothing),
// // fold/build fusion
// (OptionalFold, [_, App(box Builtin(OptionalBuild), [_, x, rest..]), rest..]) => {
// normalize_whnf(&App(bx(x.clone()), rest.to_vec()))
@@ -175,13 +174,15 @@ where
break dhall_expr!(g Natural (λ(x : Natural) -> x + 1) 0);
}
}
- (NaturalFold, Some(NaturalLit(0)), [_, _, _, zero]) => Rc::clone(zero),
+ (NaturalFold, Some(NaturalLit(0)), [_, _, _, zero]) => {
+ SubExpr::clone(zero)
+ }
(NaturalFold, Some(NaturalLit(n)), [_, t, succ, zero]) => {
let fold = rc(Builtin(NaturalFold));
let n = rc(NaturalLit(n - 1));
- let t = Rc::clone(t);
- let succ = Rc::clone(succ);
- let zero = Rc::clone(zero);
+ let t = SubExpr::clone(t);
+ let succ = SubExpr::clone(succ);
+ let zero = SubExpr::clone(zero);
dhall_expr!(succ (fold n t succ zero))
}
// (NaturalFold, Some(App(f2, args2)), _) => {
@@ -273,7 +274,7 @@ where
}
(TextAppend, TextLit(x), TextLit(y)) => TextLit(x + y),
(ListAppend, EmptyListLit(t), EmptyListLit(_)) => {
- EmptyListLit(Rc::clone(t))
+ EmptyListLit(SubExpr::clone(t))
}
(ListAppend, EmptyListLit(_), _) => return y,
(ListAppend, _, EmptyListLit(_)) => return x,
@@ -326,7 +327,7 @@ where
_ => rc(Projection(e, ls.clone())),
}
}
- _ => Rc::clone(e),
+ _ => SubExpr::clone(e),
}
}
@@ -344,5 +345,5 @@ where
S: fmt::Debug,
A: fmt::Debug,
{
- map_subexpr_rc(&normalize_whnf(&e), |x| normalize(Rc::clone(x)))
+ map_subexpr_rc(&normalize_whnf(&e), |x| normalize(SubExpr::clone(x)))
}
diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs
index f21721d..e769c7f 100644
--- a/dhall/src/typecheck.rs
+++ b/dhall/src/typecheck.rs
@@ -1,7 +1,6 @@
#![allow(non_snake_case)]
use std::collections::HashSet;
use std::fmt;
-use std::rc::Rc;
use crate::normalize::normalize;
use dhall_core;
@@ -113,7 +112,7 @@ where
go::<S, T>(&mut ctx, eL0, eR0)
}
-fn type_of_builtin<S>(b: Builtin) -> Rc<Expr<S, X>> {
+fn type_of_builtin<S>(b: Builtin) -> SubExpr<S, X> {
use dhall_core::Builtin::*;
match b {
Bool | Natural | Integer | Double | Text => dhall_expr!(Type),
@@ -184,16 +183,15 @@ fn type_of_builtin<S>(b: Builtin) -> Rc<Expr<S, X>> {
/// is not necessary for just type-checking. If you actually care about the
/// returned type then you may want to `normalize` it afterwards.
pub fn type_with<S>(
- ctx: &Context<Label, Rc<Expr<S, X>>>,
- e: Rc<Expr<S, X>>,
-) -> Result<Rc<Expr<S, X>>, TypeError<S>>
+ ctx: &Context<Label, SubExpr<S, X>>,
+ e: SubExpr<S, X>,
+) -> Result<SubExpr<S, X>, TypeError<S>>
where
S: ::std::fmt::Debug,
{
use dhall_core::BinOp::*;
use dhall_core::Builtin::*;
use dhall_core::Const::*;
- use dhall_core::Expr;
use dhall_core::Expr::*;
let mkerr = |msg: TypeMessage<_>| TypeError::new(ctx, e.clone(), msg);
let ensure_const = |x: &SubExpr<_, _>, msg: TypeMessage<_>| match x.as_ref()
@@ -266,7 +264,7 @@ where
return Err(mkerr(NotAFunction(f.clone(), tf)));
}
};
- let tA = normalize(Rc::clone(tA));
+ let tA = normalize(SubExpr::clone(tA));
let tA2 = normalized_type_with(ctx, a.clone())?;
if prop_equal(tA.as_ref(), tA2.as_ref()) {
let vx0 = &V(x.clone(), 0);
@@ -280,9 +278,9 @@ where
}
Let(f, mt, r, b) => {
let r = if let Some(t) = mt {
- rc(Annot(Rc::clone(r), Rc::clone(t)))
+ rc(Annot(SubExpr::clone(r), SubExpr::clone(t)))
} else {
- Rc::clone(r)
+ SubExpr::clone(r)
};
let tR = type_with(ctx, r)?;
@@ -351,7 +349,7 @@ where
EmptyListLit(t) => {
let s = normalized_type_with(ctx, t.clone())?;
ensure_is_type(s, InvalidListType(t.clone()))?;
- let t = normalize(Rc::clone(t));
+ let t = normalize(SubExpr::clone(t));
return Ok(dhall_expr!(List t));
}
NEListLit(xs) => {
@@ -377,7 +375,7 @@ where
return Ok(dhall_expr!(Optional t));
}
NEOptionalLit(x) => {
- let t: Rc<Expr<_, _>> = type_with(ctx, x.clone())?;
+ let t: SubExpr<_, _> = type_with(ctx, x.clone())?;
let s = normalized_type_with(ctx, t.clone())?;
ensure_is_type(s, InvalidOptionalType(t.clone()))?;
let t = normalize(t);
@@ -451,9 +449,9 @@ where
}
pub fn normalized_type_with<S>(
- ctx: &Context<Label, Rc<Expr<S, X>>>,
- e: Rc<Expr<S, X>>,
-) -> Result<Rc<Expr<S, X>>, TypeError<S>>
+ ctx: &Context<Label, SubExpr<S, X>>,
+ e: SubExpr<S, X>,
+) -> Result<SubExpr<S, X>, TypeError<S>>
where
S: ::std::fmt::Debug,
{
@@ -464,8 +462,8 @@ where
/// expression must be closed (i.e. no free variables), otherwise type-checking
/// will fail.
pub fn type_of<S: ::std::fmt::Debug>(
- e: Rc<Expr<S, X>>,
-) -> Result<Rc<Expr<S, X>>, TypeError<S>> {
+ e: SubExpr<S, X>,
+) -> Result<SubExpr<S, X>, TypeError<S>> {
let ctx = Context::new();
type_with(&ctx, e) //.map(|e| e.into_owned())
}
@@ -474,63 +472,58 @@ pub fn type_of<S: ::std::fmt::Debug>(
#[derive(Debug)]
pub enum TypeMessage<S> {
UnboundVariable,
- InvalidInputType(Rc<Expr<S, X>>),
- InvalidOutputType(Rc<Expr<S, X>>),
- NotAFunction(Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- TypeMismatch(
- Rc<Expr<S, X>>,
- Rc<Expr<S, X>>,
- Rc<Expr<S, X>>,
- Rc<Expr<S, X>>,
- ),
- AnnotMismatch(Rc<Expr<S, X>>, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
+ InvalidInputType(SubExpr<S, X>),
+ InvalidOutputType(SubExpr<S, X>),
+ NotAFunction(SubExpr<S, X>, SubExpr<S, X>),
+ TypeMismatch(SubExpr<S, X>, SubExpr<S, X>, SubExpr<S, X>, SubExpr<S, X>),
+ AnnotMismatch(SubExpr<S, X>, SubExpr<S, X>, SubExpr<S, X>),
Untyped,
- InvalidListElement(usize, Rc<Expr<S, X>>, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- InvalidListType(Rc<Expr<S, X>>),
- InvalidOptionalElement(Rc<Expr<S, X>>, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
+ InvalidListElement(usize, SubExpr<S, X>, SubExpr<S, X>, SubExpr<S, X>),
+ InvalidListType(SubExpr<S, X>),
+ InvalidOptionalElement(SubExpr<S, X>, SubExpr<S, X>, SubExpr<S, X>),
InvalidOptionalLiteral(usize),
- InvalidOptionalType(Rc<Expr<S, X>>),
- InvalidPredicate(Rc<Expr<S, X>>, Rc<Expr<S, X>>),
+ InvalidOptionalType(SubExpr<S, X>),
+ InvalidPredicate(SubExpr<S, X>, SubExpr<S, X>),
IfBranchMismatch(
- Rc<Expr<S, X>>,
- Rc<Expr<S, X>>,
- Rc<Expr<S, X>>,
- Rc<Expr<S, X>>,
+ SubExpr<S, X>,
+ SubExpr<S, X>,
+ SubExpr<S, X>,
+ SubExpr<S, X>,
),
- IfBranchMustBeTerm(bool, Rc<Expr<S, X>>, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- InvalidField(Label, Rc<Expr<S, X>>),
- InvalidFieldType(Label, Rc<Expr<S, X>>),
- InvalidAlternative(Label, Rc<Expr<S, X>>),
- InvalidAlternativeType(Label, Rc<Expr<S, X>>),
+ IfBranchMustBeTerm(bool, SubExpr<S, X>, SubExpr<S, X>, SubExpr<S, X>),
+ InvalidField(Label, SubExpr<S, X>),
+ InvalidFieldType(Label, SubExpr<S, X>),
+ InvalidAlternative(Label, SubExpr<S, X>),
+ InvalidAlternativeType(Label, SubExpr<S, X>),
DuplicateAlternative(Label),
- MustCombineARecord(Rc<Expr<S, X>>, Rc<Expr<S, X>>),
+ MustCombineARecord(SubExpr<S, X>, SubExpr<S, X>),
FieldCollision(Label),
- MustMergeARecord(Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- MustMergeUnion(Rc<Expr<S, X>>, Rc<Expr<S, X>>),
+ MustMergeARecord(SubExpr<S, X>, SubExpr<S, X>),
+ MustMergeUnion(SubExpr<S, X>, SubExpr<S, X>),
UnusedHandler(HashSet<Label>),
MissingHandler(HashSet<Label>),
- HandlerInputTypeMismatch(Label, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- HandlerOutputTypeMismatch(Label, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- HandlerNotAFunction(Label, Rc<Expr<S, X>>),
- NotARecord(Label, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- MissingField(Label, Rc<Expr<S, X>>),
- BinOpTypeMismatch(BinOp, Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- NoDependentLet(Rc<Expr<S, X>>, Rc<Expr<S, X>>),
- NoDependentTypes(Rc<Expr<S, X>>, Rc<Expr<S, X>>),
+ HandlerInputTypeMismatch(Label, SubExpr<S, X>, SubExpr<S, X>),
+ HandlerOutputTypeMismatch(Label, SubExpr<S, X>, SubExpr<S, X>),
+ HandlerNotAFunction(Label, SubExpr<S, X>),
+ NotARecord(Label, SubExpr<S, X>, SubExpr<S, X>),
+ MissingField(Label, SubExpr<S, X>),
+ BinOpTypeMismatch(BinOp, SubExpr<S, X>, SubExpr<S, X>),
+ NoDependentLet(SubExpr<S, X>, SubExpr<S, X>),
+ NoDependentTypes(SubExpr<S, X>, SubExpr<S, X>),
}
/// A structured type error that includes context
#[derive(Debug)]
pub struct TypeError<S> {
- pub context: Context<Label, Rc<Expr<S, X>>>,
- pub current: Rc<Expr<S, X>>,
+ pub context: Context<Label, SubExpr<S, X>>,
+ pub current: SubExpr<S, X>,
pub type_message: TypeMessage<S>,
}
impl<S> TypeError<S> {
pub fn new(
- context: &Context<Label, Rc<Expr<S, X>>>,
- current: Rc<Expr<S, X>>,
+ context: &Context<Label, SubExpr<S, X>>,
+ current: SubExpr<S, X>,
type_message: TypeMessage<S>,
) -> Self {
TypeError {