From 69267c7cc108a2f5db35c52a71afaa5be7be7355 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 18 Apr 2019 14:10:03 +0200 Subject: Avoid an unnecessary unroll() --- dhall_core/src/core.rs | 4 +-- dhall_core/src/visitor.rs | 75 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 52 insertions(+), 27 deletions(-) (limited to 'dhall_core') diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index 7f9fd14..158abe1 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -408,9 +408,8 @@ impl Expr { ) -> SubExpr where N: Clone, - E2: Clone, { - rc(self.visit(&mut visitor::SquashEmbedVisitor(f))) + trivial_result(self.visit(&mut visitor::SquashEmbedVisitor(f))) } } @@ -427,7 +426,6 @@ impl Expr { } pub fn embed_absurd(&self) -> Expr { self.visit(&mut visitor::EmbedAbsurdVisitor) - // self.visit(&mut visitor::SquashEmbedVisitor(|e| match *e {})) } } diff --git a/dhall_core/src/visitor.rs b/dhall_core/src/visitor.rs index dcd860e..c2b0d06 100644 --- a/dhall_core/src/visitor.rs +++ b/dhall_core/src/visitor.rs @@ -541,37 +541,64 @@ where pub struct SquashEmbedVisitor(pub F1); -impl<'a, 'b, N, E, E2, F1> - ExprFInFallibleVisitor< - 'a, - SubExpr, - SubExpr, - Label, - Label, - N, - N, - E, - E2, - > for &'b mut SquashEmbedVisitor +impl<'a, 'b, N, E1, E2, F1> + ExprFVeryGenericVisitor<'a, SubExpr, SubExpr, Label, N, E1> + for &'b mut SquashEmbedVisitor where N: Clone + 'a, - E2: Clone, - F1: FnMut(&E) -> SubExpr, + F1: FnMut(&E1) -> SubExpr, { - fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { - rc(subexpr.as_ref().visit(&mut **self)) + type Error = X; + type SE2 = SubExpr; + type L2 = Label; + type N2 = N; + type E2 = E2; + + fn visit_subexpr( + &mut self, + subexpr: &'a SubExpr, + ) -> Result { + Ok(subexpr.as_ref().visit(&mut **self)?) } - fn visit_note(self, note: &'a N) -> N { - N::clone(note) + + fn visit_label( + &mut self, + label: &'a Label, + ) -> Result { + Ok(Label::clone(label)) } - fn visit_embed(self, _: &'a E) -> E2 { - unreachable!() + + fn visit_binder( + mut self, + label: &'a Label, + subexpr: &'a SubExpr, + ) -> Result<(Self::L2, Self::SE2), Self::Error> { + Ok((self.visit_label(label)?, self.visit_subexpr(subexpr)?)) } - fn visit_embed_squash(self, embed: &'a E) -> Expr { - (self.0)(embed).unroll() + + fn visit_embed_squash( + self, + embed: &'a E1, + ) -> Result, Self::Error> { + Ok((self.0)(embed)) } - fn visit_label(&mut self, label: &'a Label) -> Label { - Label::clone(label) + + fn visit_note_squash( + mut self, + note: &'a N, + subexpr: &'a SubExpr, + ) -> Result, Self::Error> { + let subexpr = self.visit_subexpr(subexpr)?; + let note = N::clone(note); + Ok(rc(ExprF::Note(note, subexpr))) + } + + // Called with the result of the map, in the non-embed/note case. + // Useful to change the result type, and/or avoid some loss of info + fn visit_resulting_exprf( + result: ExprF, + ) -> Result, Self::Error> { + Ok(rc(result)) } } -- cgit v1.2.3