diff options
author | Nadrieril Feneanar | 2019-12-24 20:41:22 +0000 |
---|---|---|
committer | GitHub | 2019-12-24 20:41:22 +0000 |
commit | 057d645a90a6b57f40f72eb7e347ba2c6219777e (patch) | |
tree | 151473a0a6cb7222fd6b4eb3abf1cfacca012aad /dhall/src/semantics/phase/typecheck.rs | |
parent | 06e75c919d999c310f8ca1c151c6a5ad6918ca08 (diff) | |
parent | 18dd5ba3ae94fd89dd27c0ae3891ac3e43ace350 (diff) |
Merge pull request #124 from Nadrieril/catchup-spec
Catchup on standard changes
Diffstat (limited to 'dhall/src/semantics/phase/typecheck.rs')
-rw-r--r-- | dhall/src/semantics/phase/typecheck.rs | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/dhall/src/semantics/phase/typecheck.rs b/dhall/src/semantics/phase/typecheck.rs index c439f74..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; @@ -235,6 +236,9 @@ fn type_of_builtin<E>(b: Builtin) -> Expr<E> { IntegerToDouble => make_type!(Integer -> Double), IntegerShow => make_type!(Integer -> Text), + IntegerNegate => make_type!(Integer -> Integer), + IntegerClamp => make_type!(Integer -> Natural), + DoubleShow => make_type!(Double -> Text), TextShow => make_type!(Text -> Text), @@ -692,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; @@ -774,7 +789,15 @@ fn type_last_layer( for l in labels { match kts.get(l) { None => return mkerr(ProjectionMissingEntry), - Some(t) => new_kts.insert(l.clone(), t.clone()), + Some(t) => { + use std::collections::hash_map::Entry; + match new_kts.entry(l.clone()) { + Entry::Occupied(_) => { + return mkerr(ProjectionDuplicateField) + } + Entry::Vacant(e) => e.insert(t.clone()), + } + } }; } @@ -784,6 +807,7 @@ fn type_last_layer( )) } ProjectionByExpr(_, _) => unimplemented!("selection by expression"), + Completion(_, _) => unimplemented!("record completion"), }; Ok(match ret { |