summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhall/src/operations/normalization.rs37
-rw-r--r--dhall/tests/spec.rs4
2 files changed, 29 insertions, 12 deletions
diff --git a/dhall/src/operations/normalization.rs b/dhall/src/operations/normalization.rs
index 908ed93..f147f85 100644
--- a/dhall/src/operations/normalization.rs
+++ b/dhall/src/operations/normalization.rs
@@ -306,16 +306,24 @@ pub fn normalize_operation(opkind: &OpKind<Nir>) -> Ret {
let mut visited: Vec<(&Label, HashMap<Label, Nir>)> = Vec::new();
let mut to_create = Vec::new();
+ // To be used when an abstract entry is reached
+ let mut abstract_nir = None;
+
for label in labels {
match current_nk {
- None => to_create.push(label),
+ None => to_create.push(label.clone()),
Some(nk) => match nk {
RecordLit(kvs) => {
current_nk =
kvs.get(label).map(|nir| nir.kind().clone());
visited.push((label, kvs));
}
- _ => return nothing_to_do(),
+ // Handle partially abstract case
+ nir => {
+ abstract_nir = Some(Nir::from_kind(nir));
+ to_create.push(label.clone());
+ current_nk = None;
+ }
},
}
}
@@ -323,12 +331,25 @@ pub fn normalize_operation(opkind: &OpKind<Nir>) -> Ret {
// Create Nir for record bottom up
let mut nir = expr.clone();
- while let Some(label) = to_create.pop() {
- let rec = RecordLit(FromIterator::from_iter(once((
- label.clone(),
- nir,
- ))));
- nir = Nir::from_kind(rec);
+ match abstract_nir {
+ // No abstract nir, creating singleton records
+ None => {
+ while let Some(label) = to_create.pop() {
+ let rec = RecordLit(FromIterator::from_iter(once((
+ label.clone(),
+ nir,
+ ))));
+ nir = Nir::from_kind(rec);
+ }
+ }
+ // Abstract nir, creating with op
+ Some(abstract_nir) => {
+ nir = Nir::from_kind(Op(OpKind::With(
+ abstract_nir,
+ to_create,
+ nir,
+ )));
+ }
}
// Update visited records
diff --git a/dhall/tests/spec.rs b/dhall/tests/spec.rs
index c93be7e..357181a 100644
--- a/dhall/tests/spec.rs
+++ b/dhall/tests/spec.rs
@@ -521,10 +521,6 @@ fn define_features() -> Vec<TestFeature> {
|| path == "simple/integerToDouble"
// TODO: fix Double/show
|| path == "prelude/JSON/number/1"
- // With builtin not implemented yet
- || path == "unit/WithCreateIntermediateRecords"
- || path == "unit/WithDesugar"
- || path == "unit/WithPartiallyAbstract"
}),
..default_feature.clone()
},