From 32051979778436ea02cb406551f126fe22ea1636 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 9 May 2019 16:53:48 +0200 Subject: ExprF need not be generic in Label --- dhall/src/core/thunk.rs | 8 +- dhall/src/core/value.rs | 4 +- dhall/src/phase/normalize.rs | 9 +- dhall/src/phase/typecheck.rs | 3 +- dhall_proc_macros/src/quote.rs | 6 +- dhall_syntax/src/core/expr.rs | 74 ++++---------- dhall_syntax/src/core/visitor.rs | 210 +++++++++++++-------------------------- dhall_syntax/src/printer.rs | 4 +- 8 files changed, 105 insertions(+), 213 deletions(-) diff --git a/dhall/src/core/thunk.rs b/dhall/src/core/thunk.rs index 51922e1..eed8685 100644 --- a/dhall/src/core/thunk.rs +++ b/dhall/src/core/thunk.rs @@ -1,7 +1,7 @@ use std::cell::{Ref, RefCell}; use std::rc::Rc; -use dhall_syntax::{ExprF, Label, X}; +use dhall_syntax::{ExprF, X}; use crate::core::context::NormalizationContext; use crate::core::context::TypecheckContext; @@ -30,7 +30,7 @@ enum ThunkInternal { /// Partially normalized value whose subexpressions have been thunked (this is returned from /// typechecking). Note that this is different from `Value::PartialExpr` because there is no /// requirement of WHNF here. - PartialExpr(ExprF), + PartialExpr(ExprF), /// Partially normalized value. /// Invariant: if the marker is `NF`, the value must be fully normalized Value(Marker, Value), @@ -121,7 +121,7 @@ impl Thunk { Thunk::new(NormalizationContext::new(), e.absurd()) } - pub(crate) fn from_partial_expr(e: ExprF) -> Thunk { + pub(crate) fn from_partial_expr(e: ExprF) -> Thunk { ThunkInternal::PartialExpr(e).into_thunk() } @@ -280,7 +280,6 @@ impl Shift for ThunkInternal { |v| Ok(v.shift(delta, var)?), |x, v| Ok(v.shift(delta, &var.under_binder(x))?), |x| Ok(X::clone(x)), - |l| Ok(Label::clone(l)), )?, ), ThunkInternal::Value(m, v) => { @@ -322,7 +321,6 @@ impl Subst for ThunkInternal { ) }, X::clone, - Label::clone, ), ), ThunkInternal::Value(_, v) => { diff --git a/dhall/src/core/value.rs b/dhall/src/core/value.rs index e91b6bc..799cfac 100644 --- a/dhall/src/core/value.rs +++ b/dhall/src/core/value.rs @@ -58,7 +58,7 @@ pub(crate) enum Value { // contiguous text values must be merged. TextLit(Vec>), // Invariant: this must not contain a value captured by one of the variants above. - PartialExpr(ExprF), + PartialExpr(ExprF), } impl Value { @@ -433,7 +433,6 @@ impl Shift for Value { |v| Ok(v.shift(delta, var)?), |x, v| Ok(v.shift(delta, &var.under_binder(x))?), |x| Ok(X::clone(x)), - |l| Ok(Label::clone(l)), )?, ), }) @@ -459,7 +458,6 @@ impl Subst for Value { ) }, X::clone, - Label::clone, )) } // Retry normalizing since substituting may allow progress diff --git a/dhall/src/phase/normalize.rs b/dhall/src/phase/normalize.rs index 52c1666..64de2a7 100644 --- a/dhall/src/phase/normalize.rs +++ b/dhall/src/phase/normalize.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use dhall_syntax::{ - BinOp, Builtin, ExprF, InterpolatedText, InterpolatedTextContents, Label, + BinOp, Builtin, ExprF, InterpolatedText, InterpolatedTextContents, NaiveDouble, X, }; @@ -356,12 +356,11 @@ pub(crate) fn normalize_whnf( } // Thunk subexpressions - let expr: ExprF = + let expr: ExprF = expr.as_ref().map_ref_with_special_handling_of_binders( |e| Thunk::new(ctx.clone(), e.clone()), |x, e| Thunk::new(ctx.skip(x), e.clone()), |_| unreachable!(), - Label::clone, ); normalize_one_layer(expr) @@ -372,7 +371,7 @@ enum Ret<'a> { RetValue(Value), RetThunk(Thunk), RetThunkRef(&'a Thunk), - RetExpr(ExprF), + RetExpr(ExprF), } fn merge_maps( @@ -521,7 +520,7 @@ fn apply_binop<'a>(o: BinOp, x: &'a Thunk, y: &'a Thunk) -> Option> { }) } -pub(crate) fn normalize_one_layer(expr: ExprF) -> Value { +pub(crate) fn normalize_one_layer(expr: ExprF) -> Value { use Ret::{RetExpr, RetThunk, RetThunkRef, RetValue}; use Value::{ BoolLit, DoubleLit, EmptyListLit, EmptyOptionalLit, IntegerLit, Lam, diff --git a/dhall/src/phase/typecheck.rs b/dhall/src/phase/typecheck.rs index 497a703..2dc97bb 100644 --- a/dhall/src/phase/typecheck.rs +++ b/dhall/src/phase/typecheck.rs @@ -421,7 +421,6 @@ fn type_with( |e| type_with(ctx, e.clone()), |_, _| unreachable!(), |_| unreachable!(), - |l| Ok(Label::clone(l)), )?; let ret = type_last_layer(ctx, &expr)?; let ret = match ret { @@ -449,7 +448,7 @@ fn type_with( /// layer. fn type_last_layer( ctx: &TypecheckContext, - e: &ExprF, + e: &ExprF, ) -> Result { use crate::error::TypeMessage::*; use dhall_syntax::BinOp::*; diff --git a/dhall_proc_macros/src/quote.rs b/dhall_proc_macros/src/quote.rs index 241ef66..00bcd45 100644 --- a/dhall_proc_macros/src/quote.rs +++ b/dhall_proc_macros/src/quote.rs @@ -24,9 +24,9 @@ pub fn subexpr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { output.into() } -// Returns an expression of type ExprF, where T is the +// Returns an expression of type ExprF, where T is the // type of the subexpressions after interpolation. -pub fn quote_exprf(expr: ExprF) -> TokenStream +pub fn quote_exprf(expr: ExprF) -> TokenStream where TS: quote::ToTokens + std::fmt::Debug, { @@ -102,7 +102,6 @@ fn quote_subexpr( |e| quote_subexpr(e, ctx), |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), |_| unreachable!(), - Label::clone, ) { Var(V(ref s, n)) => { match ctx.lookup(s, n) { @@ -136,7 +135,6 @@ fn quote_expr(expr: &Expr, ctx: &Context) -> TokenStream { |e| quote_subexpr(e, ctx), |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), |_| unreachable!(), - Label::clone, ) { Var(V(ref s, n)) => { match ctx.lookup(s, n) { diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs index 1a33ed1..3b73d88 100644 --- a/dhall_syntax/src/core/expr.rs +++ b/dhall_syntax/src/core/expr.rs @@ -150,14 +150,14 @@ impl std::cmp::PartialEq for SubExpr { impl std::cmp::Eq for SubExpr {} -pub type Expr = ExprF, Label, Embed>; +pub type Expr = ExprF, Embed>; /// Syntax tree for expressions // Having the recursion out of the enum definition enables writing // much more generic code and improves pattern-matching behind // smart pointers. #[derive(Debug, Clone, PartialEq, Eq)] -pub enum ExprF { +pub enum ExprF { Const(Const), /// `x` /// `x@n` @@ -218,110 +218,79 @@ pub enum ExprF { Embed(Embed), } -impl ExprF { +impl ExprF { pub(crate) fn visit<'a, V, Return>(&'a self, v: V) -> Return where - V: visitor::GenericVisitor<&'a ExprF, Return>, + V: visitor::GenericVisitor<&'a ExprF, Return>, { v.visit(self) } - pub fn traverse_ref_with_special_handling_of_binders<'a, SE2, L2, E2, Err>( + pub fn traverse_ref_with_special_handling_of_binders<'a, SE2, E2, Err>( &'a self, visit_subexpr: impl FnMut(&'a SE) -> Result, - visit_under_binder: impl FnOnce(&'a L, &'a SE) -> Result, + visit_under_binder: impl FnOnce(&'a Label, &'a SE) -> Result, visit_embed: impl FnOnce(&'a E) -> Result, - visit_label: impl FnMut(&'a L) -> Result, - ) -> Result, Err> - where - L: Ord, - L2: Ord, - { + ) -> Result, Err> { self.visit(visitor::TraverseRefWithBindersVisitor { visit_subexpr, visit_under_binder, visit_embed, - visit_label, }) } - fn traverse_ref<'a, SE2, L2, E2, Err>( + fn traverse_ref<'a, SE2, E2, Err>( &'a self, visit_subexpr: impl FnMut(&'a SE) -> Result, visit_embed: impl FnOnce(&'a E) -> Result, - visit_label: impl FnMut(&'a L) -> Result, - ) -> Result, Err> - where - L: Ord, - L2: Ord, - { + ) -> Result, Err> { self.visit(visitor::TraverseRefVisitor { visit_subexpr, visit_embed, - visit_label, }) } - pub fn map_ref_with_special_handling_of_binders<'a, SE2, L2, E2>( + pub fn map_ref_with_special_handling_of_binders<'a, SE2, E2>( &'a self, mut map_subexpr: impl FnMut(&'a SE) -> SE2, - mut map_under_binder: impl FnMut(&'a L, &'a SE) -> SE2, + mut map_under_binder: impl FnMut(&'a Label, &'a SE) -> SE2, map_embed: impl FnOnce(&'a E) -> E2, - mut map_label: impl FnMut(&'a L) -> L2, - ) -> ExprF - where - L: Ord, - L2: Ord, - { + ) -> ExprF { 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_embed(x)), - |x| Ok(map_label(x)), )) } - pub fn map_ref<'a, SE2, L2, E2>( + pub fn map_ref<'a, SE2, E2>( &'a self, mut map_subexpr: impl FnMut(&'a SE) -> SE2, map_embed: impl FnOnce(&'a E) -> E2, - mut map_label: impl FnMut(&'a L) -> L2, - ) -> ExprF - where - L: Ord, - L2: Ord, - { - trivial_result(self.traverse_ref( - |x| Ok(map_subexpr(x)), - |x| Ok(map_embed(x)), - |x| Ok(map_label(x)), - )) + ) -> ExprF { + trivial_result( + self.traverse_ref(|x| Ok(map_subexpr(x)), |x| Ok(map_embed(x))), + ) } pub fn traverse_ref_simple<'a, SE2, Err>( &'a self, visit_subexpr: impl FnMut(&'a SE) -> Result, - ) -> Result, Err> + ) -> Result, Err> where - L: Ord + Clone, E: Clone, { - self.traverse_ref( - visit_subexpr, - |x| Ok(E::clone(x)), - |x| Ok(L::clone(x)), - ) + self.traverse_ref(visit_subexpr, |x| Ok(E::clone(x))) } pub fn map_ref_simple<'a, SE2>( &'a self, map_subexpr: impl Fn(&'a SE) -> SE2, - ) -> ExprF + ) -> ExprF where - L: Ord + Clone, E: Clone, { - self.map_ref(map_subexpr, E::clone, L::clone) + self.map_ref(map_subexpr, E::clone) } } @@ -411,7 +380,6 @@ impl SubExpr { map_expr, map_under_binder, |_| unreachable!(), - Label::clone, )), } } diff --git a/dhall_syntax/src/core/visitor.rs b/dhall_syntax/src/core/visitor.rs index 1377849..dd539e3 100644 --- a/dhall_syntax/src/core/visitor.rs +++ b/dhall_syntax/src/core/visitor.rs @@ -16,41 +16,37 @@ pub trait GenericVisitor: Sized { /// or just one, and Rust is ok with either. See for example TraverseRefVisitor /// and TraverseEmbedVisitor. /// This is very generic. For a more legible trait, see ExprFInFallibleVisitor -pub trait ExprFVeryGenericVisitor<'a, Ret, SE1, L1, E1>: Sized { +pub trait ExprFVeryGenericVisitor<'a, Ret, SE1, E1>: Sized { type Error; type SE2; - type L2; type E2; fn visit_subexpr( &mut self, subexpr: &'a SE1, ) -> Result; - fn visit_label(&mut self, label: &'a L1) -> Result; - fn visit_binder( + fn visit_subexpr_under_binder( self, - label: &'a L1, + label: &'a Label, subexpr: &'a SE1, - ) -> Result<(Self::L2, Self::SE2), Self::Error>; + ) -> Result; fn visit_embed_squash(self, embed: &'a E1) -> Result; // Called with the result of the map, in the non-embed case. // Useful to change the result type, and/or avoid some loss of info fn visit_resulting_exprf( - result: ExprF, + result: ExprF, ) -> Result; } -impl<'a, T, Ret, SE1, L1, E1> - GenericVisitor<&'a ExprF, Result> for T +impl<'a, T, Ret, SE1, E1> + GenericVisitor<&'a ExprF, Result> for T where - L1: Ord, - T::L2: Ord, - T: ExprFVeryGenericVisitor<'a, Ret, SE1, L1, E1>, + T: ExprFVeryGenericVisitor<'a, Ret, SE1, E1>, { - fn visit(self, input: &'a ExprF) -> Result { + fn visit(self, input: &'a ExprF) -> Result { fn vec<'a, T, U, Err, F: FnMut(&'a T) -> Result>( x: &'a [T], f: F, @@ -66,32 +62,28 @@ where None => None, }) } - fn vecmap<'a, V, Ret, SE, L, E>( - x: &'a Vec<(L, SE)>, + fn vecmap<'a, V, Ret, SE, E>( + x: &'a Vec<(Label, SE)>, mut v: V, - ) -> Result, V::Error> + ) -> Result, V::Error> where - L: Ord, - V::L2: Ord, - V: ExprFVeryGenericVisitor<'a, Ret, SE, L, E>, + V: ExprFVeryGenericVisitor<'a, Ret, SE, E>, { x.iter() - .map(|(k, x)| Ok((v.visit_label(k)?, v.visit_subexpr(x)?))) + .map(|(k, x)| Ok((k.clone(), v.visit_subexpr(x)?))) .collect() } - fn vecoptmap<'a, V, Ret, SE, L, E>( - x: &'a Vec<(L, Option)>, + fn vecoptmap<'a, V, Ret, SE, E>( + x: &'a Vec<(Label, Option)>, mut v: V, - ) -> Result)>, V::Error> + ) -> Result)>, V::Error> where - L: Ord, - V::L2: Ord, - V: ExprFVeryGenericVisitor<'a, Ret, SE, L, E>, + V: ExprFVeryGenericVisitor<'a, Ret, SE, E>, { x.iter() .map(|(k, x)| { Ok(( - v.visit_label(k)?, + k.clone(), match x { Some(x) => Some(v.visit_subexpr(x)?), None => None, @@ -104,22 +96,22 @@ where let mut v = self; use crate::ExprF::*; T::visit_resulting_exprf(match input { - Var(V(l, n)) => Var(V(v.visit_label(l)?, *n)), + Var(v) => Var(v.clone()), Lam(l, t, e) => { let t = v.visit_subexpr(t)?; - let (l, e) = v.visit_binder(l, e)?; - Lam(l, t, e) + let e = v.visit_subexpr_under_binder(l, e)?; + Lam(l.clone(), t, e) } Pi(l, t, e) => { let t = v.visit_subexpr(t)?; - let (l, e) = v.visit_binder(l, e)?; - Pi(l, t, e) + let e = v.visit_subexpr_under_binder(l, e)?; + Pi(l.clone(), t, e) } Let(l, t, a, e) => { let t = opt(t, &mut |e| v.visit_subexpr(e))?; let a = v.visit_subexpr(a)?; - let (l, e) = v.visit_binder(l, e)?; - Let(l, t, a, e) + let e = v.visit_subexpr_under_binder(l, e)?; + Let(l.clone(), t, a, e) } App(f, a) => App(v.visit_subexpr(f)?, v.visit_subexpr(a)?), Annot(x, t) => Annot(v.visit_subexpr(x)?, v.visit_subexpr(t)?), @@ -148,20 +140,16 @@ where RecordType(kts) => RecordType(vecmap(kts, v)?), RecordLit(kvs) => RecordLit(vecmap(kvs, v)?), UnionType(kts) => UnionType(vecoptmap(kts, v)?), - UnionLit(k, x, kts) => UnionLit( - v.visit_label(k)?, - v.visit_subexpr(x)?, - vecoptmap(kts, v)?, - ), + UnionLit(k, x, kts) => { + UnionLit(k.clone(), v.visit_subexpr(x)?, vecoptmap(kts, v)?) + } Merge(x, y, t) => Merge( v.visit_subexpr(x)?, v.visit_subexpr(y)?, opt(t, |e| v.visit_subexpr(e))?, ), - Field(e, l) => Field(v.visit_subexpr(e)?, v.visit_label(l)?), - Projection(e, ls) => { - Projection(v.visit_subexpr(e)?, vec(ls, |l| v.visit_label(l))?) - } + Field(e, l) => Field(v.visit_subexpr(e)?, l.clone()), + Projection(e, ls) => Projection(v.visit_subexpr(e)?, ls.clone()), Embed(a) => return v.visit_embed_squash(a), }) } @@ -169,48 +157,35 @@ where /// Like ExprFVeryGenericVisitor, but sets the return /// type to ExprF<_> -pub trait ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>: Sized { +pub trait ExprFFallibleVisitor<'a, SE1, SE2, E1, E2>: Sized { type Error; fn visit_subexpr(&mut self, subexpr: &'a SE1) -> Result; - fn visit_label(&mut self, label: &'a L1) -> Result; fn visit_embed(self, embed: &'a E1) -> Result; fn visit_subexpr_under_binder( mut self, - _label: &'a L1, + _label: &'a Label, subexpr: &'a SE1, ) -> Result { self.visit_subexpr(subexpr) } - fn visit_binder( - mut self, - label: &'a L1, - subexpr: &'a SE1, - ) -> Result<(L2, SE2), Self::Error> { - Ok(( - self.visit_label(label)?, - self.visit_subexpr_under_binder(label, subexpr)?, - )) - } - fn visit_embed_squash( self, embed: &'a E1, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(ExprF::Embed(self.visit_embed(embed)?)) } } -impl<'a, T, SE1, SE2, L1, L2, E1, E2> - ExprFVeryGenericVisitor<'a, ExprF, SE1, L1, E1> for T +impl<'a, T, SE1, SE2, E1, E2> + ExprFVeryGenericVisitor<'a, ExprF, SE1, E1> for T where - T: ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>, + T: ExprFFallibleVisitor<'a, SE1, SE2, E1, E2>, { type Error = T::Error; type SE2 = SE2; - type L2 = L2; type E2 = E2; fn visit_subexpr( @@ -220,127 +195,105 @@ where self.visit_subexpr(subexpr) } - fn visit_label(&mut self, label: &'a L1) -> Result { - self.visit_label(label) - } - - fn visit_binder( + fn visit_subexpr_under_binder( self, - label: &'a L1, + label: &'a Label, subexpr: &'a SE1, - ) -> Result<(Self::L2, Self::SE2), Self::Error> { - self.visit_binder(label, subexpr) + ) -> Result { + self.visit_subexpr_under_binder(label, subexpr) } fn visit_embed_squash( self, embed: &'a E1, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { self.visit_embed_squash(embed) } // Called with the result of the map, in the non-embed case. // Useful to change the result type, and/or avoid some loss of info fn visit_resulting_exprf( - result: ExprF, - ) -> Result, Self::Error> { + result: ExprF, + ) -> Result, Self::Error> { Ok(result) } } /// Like ExprFFallibleVisitor, but without the error handling. -pub trait ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>: Sized { +pub trait ExprFInFallibleVisitor<'a, SE1, SE2, E1, E2>: Sized { fn visit_subexpr(&mut self, subexpr: &'a SE1) -> SE2; - fn visit_label(&mut self, label: &'a L1) -> L2; fn visit_embed(self, embed: &'a E1) -> E2; fn visit_subexpr_under_binder( mut self, - _label: &'a L1, + _label: &'a Label, subexpr: &'a SE1, ) -> SE2 { self.visit_subexpr(subexpr) } - fn visit_binder(mut self, label: &'a L1, subexpr: &'a SE1) -> (L2, SE2) { - ( - self.visit_label(label), - self.visit_subexpr_under_binder(label, subexpr), - ) - } - - fn visit_embed_squash(self, embed: &'a E1) -> ExprF { + fn visit_embed_squash(self, embed: &'a E1) -> ExprF { ExprF::Embed(self.visit_embed(embed)) } } struct InfallibleWrapper(T); -impl<'a, T, SE1, SE2, L1, L2, E1, E2> - ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2> for InfallibleWrapper +impl<'a, T, SE1, SE2, E1, E2> ExprFFallibleVisitor<'a, SE1, SE2, E1, E2> + for InfallibleWrapper where - T: ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>, + T: ExprFInFallibleVisitor<'a, SE1, SE2, E1, E2>, { type Error = X; fn visit_subexpr(&mut self, subexpr: &'a SE1) -> Result { Ok(self.0.visit_subexpr(subexpr)) } - fn visit_label(&mut self, label: &'a L1) -> Result { - Ok(self.0.visit_label(label)) - } fn visit_embed(self, embed: &'a E1) -> Result { Ok(self.0.visit_embed(embed)) } - fn visit_binder( + fn visit_subexpr_under_binder( self, - label: &'a L1, + label: &'a Label, subexpr: &'a SE1, - ) -> Result<(L2, SE2), Self::Error> { - Ok(self.0.visit_binder(label, subexpr)) + ) -> Result { + Ok(self.0.visit_subexpr_under_binder(label, subexpr)) } fn visit_embed_squash( self, embed: &'a E1, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(self.0.visit_embed_squash(embed)) } } -impl<'a, T, SE1, SE2, L1, L2, E1, E2> - GenericVisitor<&'a ExprF, ExprF> for T +impl<'a, T, SE1, SE2, E1, E2> GenericVisitor<&'a ExprF, ExprF> + for T where - L1: Ord, - L2: Ord, - T: ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>, + T: ExprFInFallibleVisitor<'a, SE1, SE2, E1, E2>, { - fn visit(self, input: &'a ExprF) -> ExprF { + fn visit(self, input: &'a ExprF) -> ExprF { trivial_result(InfallibleWrapper(self).visit(input)) } } -pub struct TraverseRefWithBindersVisitor { +pub struct TraverseRefWithBindersVisitor { pub visit_subexpr: F1, pub visit_under_binder: F2, pub visit_embed: F4, - pub visit_label: F5, } -impl<'a, SE, L, E, SE2, L2, E2, Err, F1, F2, F4, F5> - ExprFFallibleVisitor<'a, SE, SE2, L, L2, E, E2> - for TraverseRefWithBindersVisitor +impl<'a, SE, E, SE2, E2, Err, F1, F2, F4> + ExprFFallibleVisitor<'a, SE, SE2, E, E2> + for TraverseRefWithBindersVisitor where SE: 'a, - L: 'a, E: 'a, - L: Ord, - L2: Ord, F1: FnMut(&'a SE) -> Result, - F2: FnOnce(&'a L, &'a SE) -> Result, + F2: FnOnce(&'a Label, &'a SE) -> Result, F4: FnOnce(&'a E) -> Result, - F5: FnMut(&'a L) -> Result, { type Error = Err; @@ -349,7 +302,7 @@ where } fn visit_subexpr_under_binder( self, - label: &'a L, + label: &'a Label, subexpr: &'a SE, ) -> Result { (self.visit_under_binder)(label, subexpr) @@ -357,29 +310,20 @@ where fn visit_embed(self, embed: &'a E) -> Result { (self.visit_embed)(embed) } - fn visit_label(&mut self, label: &'a L) -> Result { - (self.visit_label)(label) - } } -pub struct TraverseRefVisitor { +pub struct TraverseRefVisitor { pub visit_subexpr: F1, pub visit_embed: F3, - pub visit_label: F4, } -impl<'a, SE, L, E, SE2, L2, E2, Err, F1, F3, F4> - ExprFFallibleVisitor<'a, SE, SE2, L, L2, E, E2> - for TraverseRefVisitor +impl<'a, SE, E, SE2, E2, Err, F1, F3> ExprFFallibleVisitor<'a, SE, SE2, E, E2> + for TraverseRefVisitor where SE: 'a, - L: 'a, E: 'a, - L: Ord, - L2: Ord, F1: FnMut(&'a SE) -> Result, F3: FnOnce(&'a E) -> Result, - F4: FnMut(&'a L) -> Result, { type Error = Err; @@ -389,15 +333,12 @@ where fn visit_embed(self, embed: &'a E) -> Result { (self.visit_embed)(embed) } - fn visit_label(&mut self, label: &'a L) -> Result { - (self.visit_label)(label) - } } pub struct TraverseEmbedVisitor(pub F1); impl<'a, 'b, N, E, E2, Err, F1> - ExprFFallibleVisitor<'a, SubExpr, SubExpr, Label, Label, E, E2> + ExprFFallibleVisitor<'a, SubExpr, SubExpr, E, E2> for &'b mut TraverseEmbedVisitor where N: Clone + 'a, @@ -414,15 +355,12 @@ where fn visit_embed(self, embed: &'a E) -> Result { (self.0)(embed) } - fn visit_label(&mut self, label: &'a Label) -> Result { - Ok(Label::clone(label)) - } } pub struct NoteAbsurdVisitor; impl<'a, 'b, N, E> - ExprFInFallibleVisitor<'a, SubExpr, SubExpr, Label, Label, E, E> + ExprFInFallibleVisitor<'a, SubExpr, SubExpr, E, E> for &'b mut NoteAbsurdVisitor where E: Clone + 'a, @@ -433,15 +371,12 @@ where fn visit_embed(self, embed: &'a E) -> E { E::clone(embed) } - fn visit_label(&mut self, label: &'a Label) -> Label { - Label::clone(label) - } } pub struct AbsurdVisitor; impl<'a, 'b, N, E> - ExprFInFallibleVisitor<'a, SubExpr, SubExpr, Label, Label, X, E> + ExprFInFallibleVisitor<'a, SubExpr, SubExpr, X, E> for &'b mut AbsurdVisitor { fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { @@ -450,7 +385,4 @@ impl<'a, 'b, N, E> fn visit_embed(self, embed: &'a X) -> E { match *embed {} } - fn visit_label(&mut self, label: &'a Label) -> Label { - Label::clone(label) - } } diff --git a/dhall_syntax/src/printer.rs b/dhall_syntax/src/printer.rs index 9f03701..0162693 100644 --- a/dhall_syntax/src/printer.rs +++ b/dhall_syntax/src/printer.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use std::fmt::{self, Display}; /// Generic instance that delegates to subexpressions -impl Display for ExprF { +impl Display for ExprF { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { use crate::ExprF::*; match self { @@ -202,7 +202,7 @@ impl Expr { f.write_str("(")?; } - // Uses the ExprF, _, _, _> instance + // Uses the ExprF, _> instance phased_self.fmt(f)?; if needs_paren { -- cgit v1.2.3