summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2019-08-04 13:00:56 +0200
committerNadrieril2019-08-06 21:40:24 +0200
commit696efe66336a268054c475fab9fe6505bdfc7b60 (patch)
tree353f9c5edd080e22455dba775fcfc5c6afc0f1fa /dhall
parent278cd9be7d93bc1eeecde05c964da5b097668016 (diff)
Add some new tests and implement import alternatives
Diffstat (limited to '')
-rw-r--r--dhall/src/error/mod.rs2
-rw-r--r--dhall/src/phase/resolve.rs4
-rw-r--r--dhall/src/phase/typecheck.rs2
-rw-r--r--dhall_syntax/src/core/expr.rs39
-rw-r--r--dhall_syntax/src/core/visitor.rs25
5 files changed, 68 insertions, 4 deletions
diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs
index aed6ccd..a0ee30a 100644
--- a/dhall/src/error/mod.rs
+++ b/dhall/src/error/mod.rs
@@ -86,7 +86,7 @@ pub(crate) enum TypeMessage {
RecordTypeMergeRequiresRecordType(Type),
RecordTypeMismatch(Type, Type, Type, Type),
UnionTypeDuplicateField,
- Unimplemented,
+ // Unimplemented,
}
impl TypeError {
diff --git a/dhall/src/phase/resolve.rs b/dhall/src/phase/resolve.rs
index f1329aa..0609694 100644
--- a/dhall/src/phase/resolve.rs
+++ b/dhall/src/phase/resolve.rs
@@ -86,7 +86,7 @@ fn do_resolve_expr(
}
}
};
- let expr = expr.traverse_embed(resolve)?;
+ let expr = expr.traverse_resolve(resolve)?;
Ok(Resolved(expr))
}
@@ -100,7 +100,7 @@ pub fn skip_resolve_expr(
let resolve = |import: &Import| -> Result<Normalized, ImportError> {
Err(ImportError::UnexpectedImport(import.clone()))
};
- let expr = expr.traverse_embed(resolve)?;
+ let expr = expr.traverse_resolve(resolve)?;
Ok(Resolved(expr))
}
diff --git a/dhall/src/phase/typecheck.rs b/dhall/src/phase/typecheck.rs
index 8551503..753d25e 100644
--- a/dhall/src/phase/typecheck.rs
+++ b/dhall/src/phase/typecheck.rs
@@ -823,7 +823,7 @@ fn type_last_layer(
RightBiasedRecordMerge => unreachable!(),
RecursiveRecordMerge => unreachable!(),
RecursiveRecordTypeMerge => unreachable!(),
- _ => return Err(mkerr(Unimplemented)),
+ ImportAlt => unreachable!("There should remain no import alternatives in a resolved expression"),
})?;
ensure_equal!(
diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs
index df2dc97..e33859b 100644
--- a/dhall_syntax/src/core/expr.rs
+++ b/dhall_syntax/src/core/expr.rs
@@ -307,6 +307,35 @@ impl<N, E> Expr<N, E> {
{
trivial_result(self.traverse_embed(|x| Ok(map_embed(x))))
}
+
+ pub fn traverse_resolve<E2, Err>(
+ &self,
+ visit_embed: impl FnMut(&E) -> Result<E2, Err>,
+ ) -> Result<Expr<N, E2>, Err>
+ where
+ N: Clone,
+ {
+ self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor(
+ visit_embed,
+ ))
+ }
+
+ pub(crate) fn traverse_resolve_with_visitor<E2, Err, F1>(
+ &self,
+ visitor: &mut visitor::ResolveVisitor<F1>,
+ ) -> Result<Expr<N, E2>, Err>
+ where
+ N: Clone,
+ F1: FnMut(&E) -> Result<E2, Err>,
+ {
+ match self {
+ ExprF::BinOp(BinOp::ImportAlt, l, r) => l
+ .as_ref()
+ .traverse_resolve_with_visitor(visitor)
+ .or(r.as_ref().traverse_resolve_with_visitor(visitor)),
+ _ => self.visit(visitor),
+ }
+ }
}
impl Expr<X, X> {
@@ -383,6 +412,16 @@ impl<N, E> SubExpr<N, E> {
)),
}
}
+
+ pub fn traverse_resolve<E2, Err>(
+ &self,
+ visit_embed: impl FnMut(&E) -> Result<E2, Err>,
+ ) -> Result<SubExpr<N, E2>, Err>
+ where
+ N: Clone,
+ {
+ Ok(self.rewrap(self.as_ref().traverse_resolve(visit_embed)?))
+ }
}
impl SubExpr<X, X> {
diff --git a/dhall_syntax/src/core/visitor.rs b/dhall_syntax/src/core/visitor.rs
index 1745fdb..b02544f 100644
--- a/dhall_syntax/src/core/visitor.rs
+++ b/dhall_syntax/src/core/visitor.rs
@@ -358,6 +358,31 @@ where
}
}
+pub struct ResolveVisitor<F1>(pub F1);
+
+impl<'a, 'b, N, E, E2, Err, F1>
+ ExprFFallibleVisitor<'a, SubExpr<N, E>, SubExpr<N, E2>, E, E2>
+ for &'b mut ResolveVisitor<F1>
+where
+ N: Clone + 'a,
+ F1: FnMut(&E) -> Result<E2, Err>,
+{
+ type Error = Err;
+
+ fn visit_subexpr(
+ &mut self,
+ subexpr: &'a SubExpr<N, E>,
+ ) -> Result<SubExpr<N, E2>, Self::Error> {
+ Ok(subexpr.rewrap(
+ subexpr
+ .as_ref()
+ .traverse_resolve_with_visitor(&mut **self)?,
+ ))
+ }
+ fn visit_embed(self, embed: &'a E) -> Result<E2, Self::Error> {
+ (self.0)(embed)
+ }
+}
pub struct NoteAbsurdVisitor;
impl<'a, 'b, N, E>