summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
Diffstat (limited to 'dhall')
-rw-r--r--dhall/build.rs3
-rw-r--r--dhall/src/error/mod.rs1
-rw-r--r--dhall/src/semantics/phase/typecheck.rs10
-rw-r--r--dhall/tests/type-errors/unit/MergeUnusedHandler.txt1
-rw-r--r--dhall/tests/type-errors/unit/RecordProjectionDuplicateFields.txt1
5 files changed, 15 insertions, 1 deletions
diff --git a/dhall/build.rs b/dhall/build.rs
index 9d97839..3e7c023 100644
--- a/dhall/build.rs
+++ b/dhall/build.rs
@@ -296,6 +296,7 @@ fn generate_tests() -> std::io::Result<()> {
// TODO: toMap
|| path == "unit/ToMap"
|| path == "unit/ToMapAnnotated"
+ || path == "unit/ToMapInferTypeFromRecord"
|| path == "simple/toMapEmptyNormalizeAnnotation"
}),
input_type: FileType::Text,
@@ -321,6 +322,7 @@ fn generate_tests() -> std::io::Result<()> {
|| path == "unit/MistypedToMap3"
|| path == "unit/MistypedToMap4"
|| path == "unit/NonRecordToMap"
+ || path == "unit/ToMapEmptyInvalidAnnotation"
|| path == "unit/ToMapWrongKind"
}),
input_type: FileType::Text,
@@ -346,6 +348,7 @@ fn generate_tests() -> std::io::Result<()> {
|| path == "unit/MistypedToMap3"
|| path == "unit/MistypedToMap4"
|| path == "unit/NonRecordToMap"
+ || path == "unit/ToMapEmptyInvalidAnnotation"
|| path == "unit/ToMapWrongKind"
}),
input_type: FileType::Text,
diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs
index 1288c12..40cccac 100644
--- a/dhall/src/error/mod.rs
+++ b/dhall/src/error/mod.rs
@@ -76,6 +76,7 @@ pub(crate) enum TypeMessage {
MergeHandlerReturnTypeMustNotBeDependent,
ProjectionMustBeRecord,
ProjectionMissingEntry,
+ ProjectionDuplicateField,
Sort,
RecordTypeDuplicateField,
RecordTypeMergeRequiresRecordType(Value),
diff --git a/dhall/src/semantics/phase/typecheck.rs b/dhall/src/semantics/phase/typecheck.rs
index c439f74..856f5c3 100644
--- a/dhall/src/semantics/phase/typecheck.rs
+++ b/dhall/src/semantics/phase/typecheck.rs
@@ -774,7 +774,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()),
+ }
+ }
};
}
diff --git a/dhall/tests/type-errors/unit/MergeUnusedHandler.txt b/dhall/tests/type-errors/unit/MergeUnusedHandler.txt
new file mode 100644
index 0000000..4b68fea
--- /dev/null
+++ b/dhall/tests/type-errors/unit/MergeUnusedHandler.txt
@@ -0,0 +1 @@
+Type error: Unhandled error
diff --git a/dhall/tests/type-errors/unit/RecordProjectionDuplicateFields.txt b/dhall/tests/type-errors/unit/RecordProjectionDuplicateFields.txt
new file mode 100644
index 0000000..4b68fea
--- /dev/null
+++ b/dhall/tests/type-errors/unit/RecordProjectionDuplicateFields.txt
@@ -0,0 +1 @@
+Type error: Unhandled error