From bb1f698c23a83f60020a72bb5be1f9a386c60d44 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 18 Apr 2019 11:58:21 +0200 Subject: Start cleaning up the mess of mapping functions --- dhall_generator/src/quote.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/quote.rs b/dhall_generator/src/quote.rs index c335666..7128511 100644 --- a/dhall_generator/src/quote.rs +++ b/dhall_generator/src/quote.rs @@ -103,7 +103,7 @@ fn quote_subexpr( ctx: &Context, ) -> TokenStream { use dhall_core::ExprF::*; - match expr.as_ref().map_ref( + match expr.as_ref().map_ref_with_special_handling_of_binders( |e| quote_subexpr(e, ctx), |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), |_| unreachable!(), @@ -138,7 +138,7 @@ fn quote_subexpr( // to be of type SubExpr<_, _>. fn quote_expr(expr: &Expr, ctx: &Context) -> TokenStream { use dhall_core::ExprF::*; - match expr.map_ref( + match expr.map_ref_with_special_handling_of_binders( |e| quote_subexpr(e, ctx), |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), |_| unreachable!(), -- cgit v1.3.1 From e68e34f361a29e0661201ac3c93a711a9884833f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 18 Apr 2019 13:15:42 +0200 Subject: Reduce duplication between mapping functions --- dhall_core/src/core.rs | 90 ++++++++++++++++---------------------------- dhall_core/src/visitor.rs | 1 - dhall_generator/src/quote.rs | 4 +- 3 files changed, 35 insertions(+), 60 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index d0e908b..7f9fd14 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -273,9 +273,21 @@ impl ExprF { }) } - pub fn map_ref<'a, SE2, L2, N2, E2, F1, F3, F4, F5>( + pub fn map_ref_with_special_handling_of_binders< + 'a, + SE2, + L2, + N2, + E2, + F1, + F2, + F3, + F4, + F5, + >( &'a self, mut map_subexpr: F1, + mut map_under_binder: F2, map_note: F3, map_embed: F4, mut map_label: F5, @@ -284,33 +296,23 @@ impl ExprF { L: Ord, L2: Ord, F1: FnMut(&'a SE) -> SE2, + F2: FnMut(&'a L, &'a SE) -> SE2, F3: FnOnce(&'a N) -> N2, F4: FnOnce(&'a E) -> E2, F5: FnMut(&'a L) -> L2, { - trivial_result(self.traverse_ref( + trivial_result(self.traverse_ref_with_special_handling_of_binders( |x| Ok(map_subexpr(x)), + |l, x| Ok(map_under_binder(l, x)), |x| Ok(map_note(x)), |x| Ok(map_embed(x)), |x| Ok(map_label(x)), )) } - pub fn map_ref_with_special_handling_of_binders< - 'a, - SE2, - L2, - N2, - E2, - F1, - F2, - F3, - F4, - F5, - >( + pub fn map_ref<'a, SE2, L2, N2, E2, F1, F3, F4, F5>( &'a self, mut map_subexpr: F1, - mut map_under_binder: F2, map_note: F3, map_embed: F4, mut map_label: F5, @@ -319,14 +321,12 @@ impl ExprF { L: Ord, L2: Ord, F1: FnMut(&'a SE) -> SE2, - F2: FnMut(&'a L, &'a SE) -> SE2, F3: FnOnce(&'a N) -> N2, F4: FnOnce(&'a E) -> E2, F5: FnMut(&'a L) -> L2, { - trivial_result(self.traverse_ref_with_special_handling_of_binders( + trivial_result(self.traverse_ref( |x| Ok(map_subexpr(x)), - |l, x| Ok(map_under_binder(l, x)), |x| Ok(map_note(x)), |x| Ok(map_embed(x)), |x| Ok(map_label(x)), @@ -362,51 +362,24 @@ impl ExprF { } impl Expr { - pub fn map_shallow( + pub fn traverse_embed( &self, - map_expr: F1, - map_note: F2, - map_embed: F3, - map_label: F4, - ) -> Expr + map_embed: F, + ) -> Result, Err> where - E: Clone, - N2: Clone, N: Clone, - F1: Fn(&Self) -> Expr, - F2: Fn(&N) -> N2, - F3: Fn(&E) -> E2, - F4: Fn(&Label) -> Label, + F: FnMut(&E) -> Result, { - self.map_ref( - |x| rc(map_expr(x.as_ref())), - map_note, - map_embed, - map_label, - ) + self.visit(&mut visitor::TraverseEmbedVisitor(map_embed)) } - pub fn map_embed(&self, map_embed: &F) -> Expr + pub fn map_embed(&self, mut map_embed: F) -> Expr where E: Clone, N: Clone, - F: Fn(&E) -> E2, + F: FnMut(&E) -> E2, { - let recurse = - |e: &Expr| -> Expr { e.map_embed(map_embed) }; - self.map_shallow(recurse, N::clone, map_embed, Label::clone) - } - - pub fn traverse_embed( - &self, - map_embed: F, - ) -> Result, Err> - where - N: Clone, - E2: Clone, - F: FnMut(&E) -> Result, - { - self.visit(&mut visitor::TraverseEmbedVisitor(map_embed)) + trivial_result(self.traverse_embed(|x| Ok(map_embed(x)))) } pub fn map_label(&self, map_label: &F) -> Self @@ -415,8 +388,10 @@ impl Expr { N: Clone, F: Fn(&Label) -> Label, { - let recurse = |e: &Self| -> Self { e.map_label(map_label) }; - self.map_shallow(recurse, N::clone, E::clone, map_label) + let recurse = |e: &SubExpr| -> SubExpr { + rc(e.as_ref().map_label(map_label)) + }; + self.map_ref(recurse, N::clone, E::clone, map_label) } pub fn roll(&self) -> SubExpr @@ -447,11 +422,12 @@ impl Expr { impl Expr { // Deprecated, use embed_absurd instead - pub fn absurd_rec(&self) -> Expr { + pub fn absurd_rec(&self) -> Expr { self.embed_absurd() } - pub fn embed_absurd(&self) -> 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 c6b7321..053932d 100644 --- a/dhall_core/src/visitor.rs +++ b/dhall_core/src/visitor.rs @@ -433,7 +433,6 @@ impl<'a, 'b, N, E, E2, Err, F1> > for &'b mut TraverseEmbedVisitor where N: Clone + 'a, - E2: Clone, F1: FnMut(&E) -> Result, { type Error = Err; diff --git a/dhall_generator/src/quote.rs b/dhall_generator/src/quote.rs index 7128511..d680288 100644 --- a/dhall_generator/src/quote.rs +++ b/dhall_generator/src/quote.rs @@ -10,7 +10,7 @@ pub fn expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let expr: SubExpr<_, Import> = parse_expr(&input_str).unwrap().unnote(); let no_import = |_: &Import| -> X { panic!("Don't use import in dhall::expr!()") }; - let expr = expr.as_ref().map_embed(&no_import); + let expr = expr.as_ref().map_embed(no_import); let output = quote_expr(&expr, &Context::new()); output.into() } @@ -20,7 +20,7 @@ pub fn subexpr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let expr: SubExpr<_, Import> = parse_expr(&input_str).unwrap().unnote(); let no_import = |_: &Import| -> X { panic!("Don't use import in dhall::subexpr!()") }; - let expr = expr.as_ref().map_embed(&no_import); + let expr = expr.as_ref().map_embed(no_import); let output = quote_subexpr(&dhall_core::rc(expr), &Context::new()); output.into() } -- cgit v1.3.1 From 9474d4939db6f844285182fc15aad74f6aa18e21 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 18 Apr 2019 14:39:56 +0200 Subject: Remove more duplication --- dhall/src/expr.rs | 2 +- dhall/src/imports.rs | 8 ++--- dhall/src/normalize.rs | 18 +++++------ dhall/src/traits/dynamic_type.rs | 2 +- dhall/src/typecheck.rs | 6 ++-- dhall_core/src/core.rs | 66 +++++++++++++++++++++------------------- dhall_core/src/visitor.rs | 30 ------------------ dhall_generator/src/quote.rs | 8 ++--- 8 files changed, 55 insertions(+), 85 deletions(-) (limited to 'dhall_generator') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 7c62a33..5885359 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -98,7 +98,7 @@ impl<'a> From> for SimpleType<'a> { #[doc(hidden)] impl<'a> From> for Typed<'a> { fn from(x: Normalized<'a>) -> Typed<'a> { - Typed(x.0.absurd(), x.1, x.2) + Typed(x.0.embed_absurd(), x.1, x.2) } } diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index b6dd80b..e367725 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -98,8 +98,8 @@ fn do_resolve_expr<'a>( } } }; - let expr = expr.as_ref().traverse_embed(resolve)?; - Ok(Resolved(rc(expr))) + let expr = expr.traverse_embed(resolve)?; + Ok(Resolved(expr)) } fn skip_resolve_expr( @@ -109,8 +109,8 @@ fn skip_resolve_expr( |import: &Import| -> Result, ImportError> { Err(ImportError::UnexpectedImport(import.clone())) }; - let expr = expr.as_ref().traverse_embed(&resolve)?; - Ok(Resolved(rc(expr))) + let expr = expr.traverse_embed(resolve)?; + Ok(Resolved(expr)) } impl<'a> Parsed<'a> { diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs index 9110624..a54e48e 100644 --- a/dhall/src/normalize.rs +++ b/dhall/src/normalize.rs @@ -325,19 +325,17 @@ fn normalize_ref(expr: &Expr>) -> Expr { }; match what_next { - Continue(e) => normalize_ref(&e.absurd_rec()), - ContinueSub(e) => normalize_ref(e.absurd().as_ref()), + Continue(e) => normalize_ref(&e.embed_absurd()), + ContinueSub(e) => normalize_ref(e.embed_absurd().as_ref()), Done(e) => e, DoneRef(e) => e.clone(), DoneRefSub(e) => e.unroll(), - DoneAsIs => match expr.map_ref_simple(ExprF::roll) { - e => e.map_ref( - SubExpr::clone, - X::clone, - |_| unreachable!(), - Label::clone, - ), - }, + DoneAsIs => expr.map_ref_simple(ExprF::roll).map_ref( + SubExpr::clone, + X::clone, + |_| unreachable!(), + Label::clone, + ), } } diff --git a/dhall/src/traits/dynamic_type.rs b/dhall/src/traits/dynamic_type.rs index d2a5414..d4faf45 100644 --- a/dhall/src/traits/dynamic_type.rs +++ b/dhall/src/traits/dynamic_type.rs @@ -35,7 +35,7 @@ impl<'a> DynamicType for Normalized<'a> { Some(t) => Ok(Cow::Borrowed(t)), None => Err(TypeError::new( &Context::new(), - self.0.absurd(), + self.0.embed_absurd(), TypeMessage::Untyped, )), } diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index de3899c..5aaeb08 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -496,7 +496,7 @@ fn type_last_layer( PhantomData ))) ); - let tx = mktype(ctx, tx.absurd())?; + let tx = mktype(ctx, tx.embed_absurd())?; ensure_equal!(&tx, a.get_type()?, { let a = a.clone(); mkerr(TypeMismatch( @@ -511,7 +511,7 @@ fn type_last_layer( x.clone(), None, a.clone().normalize().embed(), - tb.absurd(), + tb.embed_absurd(), )), )?; } @@ -675,7 +675,7 @@ fn type_last_layer( } Field(r, x) => match r.get_type()?.unroll_ref()?.as_ref() { RecordType(kts) => match kts.get(&x) { - Some(t) => Ok(RetExpr(t.unroll().absurd_rec())), + Some(t) => Ok(RetExpr(t.unroll().embed_absurd())), None => Err(mkerr(MissingRecordField(x, r))), }, _ => { diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index 158abe1..65762f2 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -205,14 +205,14 @@ pub enum ExprF { } impl ExprF { - pub fn visit<'a, V, Return>(&'a self, v: V) -> Return + pub(crate) fn visit<'a, V, Return>(&'a self, v: V) -> Return where V: visitor::GenericVisitor<&'a ExprF, Return>, { v.visit(self) } - pub fn traverse_ref_with_special_handling_of_binders< + fn traverse_ref_with_special_handling_of_binders< 'a, SE2, L2, @@ -250,7 +250,7 @@ impl ExprF { }) } - pub fn traverse_ref<'a, SE2, L2, N2, E2, Err, F1, F3, F4, F5>( + fn traverse_ref<'a, SE2, L2, N2, E2, Err, F1, F3, F4, F5>( &'a self, visit_subexpr: F1, visit_note: F3, @@ -343,7 +343,12 @@ impl ExprF { E: Clone, F1: FnMut(&'a SE) -> Result, { - self.visit(visitor::TraverseRefSimpleVisitor { visit_subexpr }) + self.traverse_ref( + visit_subexpr, + |x| Ok(N::clone(x)), + |x| Ok(E::clone(x)), + |x| Ok(L::clone(x)), + ) } pub fn map_ref_simple<'a, SE2, F1>( @@ -351,49 +356,35 @@ impl ExprF { map_subexpr: F1, ) -> ExprF where - L: Ord, - L: Clone, + L: Ord + Clone, N: Clone, E: Clone, F1: Fn(&'a SE) -> SE2, { - trivial_result(self.traverse_ref_simple(|x| Ok(map_subexpr(x)))) + self.map_ref(map_subexpr, N::clone, E::clone, L::clone) } } impl Expr { - pub fn traverse_embed( + fn traverse_embed( &self, - map_embed: F, + visit_embed: F, ) -> Result, Err> where N: Clone, F: FnMut(&E) -> Result, { - self.visit(&mut visitor::TraverseEmbedVisitor(map_embed)) + self.visit(&mut visitor::TraverseEmbedVisitor(visit_embed)) } - pub fn map_embed(&self, mut map_embed: F) -> Expr + fn map_embed(&self, mut map_embed: F) -> Expr where - E: Clone, N: Clone, F: FnMut(&E) -> E2, { trivial_result(self.traverse_embed(|x| Ok(map_embed(x)))) } - pub fn map_label(&self, map_label: &F) -> Self - where - E: Clone, - N: Clone, - F: Fn(&Label) -> Label, - { - let recurse = |e: &SubExpr| -> SubExpr { - rc(e.as_ref().map_label(map_label)) - }; - self.map_ref(recurse, N::clone, E::clone, map_label) - } - pub fn roll(&self) -> SubExpr where N: Clone, @@ -420,10 +411,6 @@ impl Expr { } impl Expr { - // Deprecated, use embed_absurd instead - pub fn absurd_rec(&self) -> Expr { - self.embed_absurd() - } pub fn embed_absurd(&self) -> Expr { self.visit(&mut visitor::EmbedAbsurdVisitor) } @@ -434,6 +421,25 @@ impl SubExpr { self.0.as_ref() } + pub fn traverse_embed( + &self, + visit_embed: F, + ) -> Result, Err> + where + N: Clone, + F: FnMut(&E) -> Result, + { + Ok(rc(self.as_ref().traverse_embed(visit_embed)?)) + } + + pub fn map_embed(&self, map_embed: F) -> SubExpr + where + N: Clone, + F: FnMut(&E) -> E2, + { + rc(self.as_ref().map_embed(map_embed)) + } + pub fn map_subexprs_with_special_handling_of_binders<'a, F1, F2>( &'a self, map_expr: F1, @@ -480,10 +486,6 @@ impl SubExpr { } impl SubExpr { - // Deprecated, use embed_absurd instead - pub fn absurd(&self) -> SubExpr { - self.embed_absurd() - } pub fn embed_absurd(&self) -> SubExpr { rc(self.as_ref().embed_absurd()) } diff --git a/dhall_core/src/visitor.rs b/dhall_core/src/visitor.rs index c2b0d06..16ad418 100644 --- a/dhall_core/src/visitor.rs +++ b/dhall_core/src/visitor.rs @@ -472,36 +472,6 @@ where } } -pub struct TraverseRefSimpleVisitor { - pub visit_subexpr: F1, -} - -impl<'a, SE, L, N, E, SE2, Err, F1> - ExprFFallibleVisitor<'a, SE, SE2, L, L, N, N, E, E> - for TraverseRefSimpleVisitor -where - SE: 'a, - L: Ord + Clone + 'a, - N: Clone + 'a, - E: Clone + 'a, - F1: FnMut(&'a SE) -> Result, -{ - type Error = Err; - - fn visit_subexpr(&mut self, subexpr: &'a SE) -> Result { - (self.visit_subexpr)(subexpr) - } - fn visit_note(self, note: &'a N) -> Result { - Ok(N::clone(note)) - } - fn visit_embed(self, embed: &'a E) -> Result { - Ok(E::clone(embed)) - } - fn visit_label(&mut self, label: &'a L) -> Result { - Ok(L::clone(label)) - } -} - pub struct TraverseEmbedVisitor(pub F1); impl<'a, 'b, N, E, E2, Err, F1> diff --git a/dhall_generator/src/quote.rs b/dhall_generator/src/quote.rs index d680288..400c12c 100644 --- a/dhall_generator/src/quote.rs +++ b/dhall_generator/src/quote.rs @@ -10,8 +10,8 @@ pub fn expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let expr: SubExpr<_, Import> = parse_expr(&input_str).unwrap().unnote(); let no_import = |_: &Import| -> X { panic!("Don't use import in dhall::expr!()") }; - let expr = expr.as_ref().map_embed(no_import); - let output = quote_expr(&expr, &Context::new()); + let expr = expr.map_embed(no_import); + let output = quote_expr(&expr.unroll(), &Context::new()); output.into() } @@ -20,8 +20,8 @@ pub fn subexpr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let expr: SubExpr<_, Import> = parse_expr(&input_str).unwrap().unnote(); let no_import = |_: &Import| -> X { panic!("Don't use import in dhall::subexpr!()") }; - let expr = expr.as_ref().map_embed(no_import); - let output = quote_subexpr(&dhall_core::rc(expr), &Context::new()); + let expr = expr.map_embed(no_import); + let output = quote_subexpr(&expr, &Context::new()); output.into() } -- cgit v1.3.1