From 5f52c5bda0277edd87323eb67dcda721cd18a9d3 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 24 Dec 2019 20:23:19 +0000 Subject: Extend merge to work on Optionals --- dhall/src/semantics/phase/normalize.rs | 24 ++++++++++++++++++++++-- dhall/src/semantics/phase/typecheck.rs | 16 ++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'dhall/src/semantics') diff --git a/dhall/src/semantics/phase/normalize.rs b/dhall/src/semantics/phase/normalize.rs index 5a0f566..459eaf1 100644 --- a/dhall/src/semantics/phase/normalize.rs +++ b/dhall/src/semantics/phase/normalize.rs @@ -590,8 +590,8 @@ pub(crate) fn normalize_one_layer( ty: &Value, ) -> ValueKind { use ValueKind::{ - AppliedBuiltin, BoolLit, DoubleLit, EmptyListLit, IntegerLit, - NEListLit, NEOptionalLit, NaturalLit, RecordLit, TextLit, + AppliedBuiltin, BoolLit, DoubleLit, EmptyListLit, EmptyOptionalLit, + IntegerLit, NEListLit, NEOptionalLit, NaturalLit, RecordLit, TextLit, UnionConstructor, UnionLit, UnionType, }; @@ -739,6 +739,26 @@ pub(crate) fn normalize_one_layer( Ret::Expr(expr) } }, + (RecordLit(kvs), EmptyOptionalLit(_)) => { + match kvs.get(&"None".into()) { + Some(h) => Ret::Value(h.clone()), + None => { + drop(handlers_borrow); + drop(variant_borrow); + Ret::Expr(expr) + } + } + } + (RecordLit(kvs), NEOptionalLit(v)) => { + match kvs.get(&"Some".into()) { + Some(h) => Ret::Value(h.app(v.clone())), + None => { + drop(handlers_borrow); + drop(variant_borrow); + Ret::Expr(expr) + } + } + } _ => { drop(handlers_borrow); drop(variant_borrow); diff --git a/dhall/src/semantics/phase/typecheck.rs b/dhall/src/semantics/phase/typecheck.rs index 7ea4951..97502d4 100644 --- a/dhall/src/semantics/phase/typecheck.rs +++ b/dhall/src/semantics/phase/typecheck.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::cmp::max; use std::collections::HashMap; @@ -695,8 +696,19 @@ fn type_last_layer( let union_type = union.get_type()?; let union_borrow = union_type.as_whnf(); let variants = match &*union_borrow { - ValueKind::UnionType(kts) => kts, - _ => return mkerr(Merge2ArgMustBeUnion(union.clone())), + ValueKind::UnionType(kts) => Cow::Borrowed(kts), + ValueKind::AppliedBuiltin(syntax::Builtin::Optional, args) + if args.len() == 1 => + { + let ty = &args[0]; + let mut kts = HashMap::new(); + kts.insert("None".into(), None); + kts.insert("Some".into(), Some(ty.clone())); + Cow::Owned(kts) + } + _ => { + return mkerr(Merge2ArgMustBeUnionOrOptional(union.clone())) + } }; let mut inferred_type = None; -- cgit v1.2.3