From 1b1c34b90bb4bf3859b05b1da6db2dcb374996bb Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 4 May 2019 14:58:18 +0200 Subject: Move `Note`s into the spine of the AST --- dhall_syntax/src/visitor.rs | 234 ++++++++++---------------------------------- 1 file changed, 49 insertions(+), 185 deletions(-) (limited to 'dhall_syntax/src/visitor.rs') diff --git a/dhall_syntax/src/visitor.rs b/dhall_syntax/src/visitor.rs index caaefce..cbaa21e 100644 --- a/dhall_syntax/src/visitor.rs +++ b/dhall_syntax/src/visitor.rs @@ -18,11 +18,10 @@ 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, N1, E1>: Sized { +pub trait ExprFVeryGenericVisitor<'a, Ret, SE1, L1, E1>: Sized { type Error; type SE2; type L2; - type N2; type E2; fn visit_subexpr( @@ -39,27 +38,21 @@ pub trait ExprFVeryGenericVisitor<'a, Ret, SE1, L1, N1, E1>: Sized { fn visit_embed_squash(self, embed: &'a E1) -> Result; - fn visit_note_squash( - self, - note: &'a N1, - subexpr: &'a SE1, - ) -> Result; - - // Called with the result of the map, in the non-embed/note case. + // 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, N1, E1> - GenericVisitor<&'a ExprF, Result> for T +impl<'a, T, Ret, SE1, L1, E1> + GenericVisitor<&'a ExprF, Result> for T where L1: Ord, T::L2: Ord, - T: ExprFVeryGenericVisitor<'a, Ret, SE1, L1, N1, E1>, + T: ExprFVeryGenericVisitor<'a, Ret, SE1, L1, 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, @@ -75,27 +68,27 @@ where None => None, }) } - fn btmap<'a, V, Ret, SE, L, N, E>( + fn btmap<'a, V, Ret, SE, L, E>( x: &'a BTreeMap, mut v: V, ) -> Result, V::Error> where L: Ord, V::L2: Ord, - V: ExprFVeryGenericVisitor<'a, Ret, SE, L, N, E>, + V: ExprFVeryGenericVisitor<'a, Ret, SE, L, E>, { x.iter() .map(|(k, x)| Ok((v.visit_label(k)?, v.visit_subexpr(x)?))) .collect() } - fn btoptmap<'a, V, Ret, SE, L, N, E>( + fn btoptmap<'a, V, Ret, SE, L, E>( x: &'a BTreeMap>, mut v: V, ) -> Result>, V::Error> where L: Ord, V::L2: Ord, - V: ExprFVeryGenericVisitor<'a, Ret, SE, L, N, E>, + V: ExprFVeryGenericVisitor<'a, Ret, SE, L, E>, { x.iter() .map(|(k, x)| { @@ -171,7 +164,6 @@ where Projection(e, ls) => { Projection(v.visit_subexpr(e)?, vec(ls, |l| v.visit_label(l))?) } - Note(n, e) => return v.visit_note_squash(n, e), Embed(a) => return v.visit_embed_squash(a), }) } @@ -179,14 +171,11 @@ where /// Like ExprFVeryGenericVisitor, but sets the return /// type to ExprF<_> -pub trait ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>: - Sized -{ +pub trait ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, 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_note(self, note: &'a N1) -> Result; fn visit_embed(self, embed: &'a E1) -> Result; fn visit_subexpr_under_binder( @@ -211,30 +200,19 @@ pub trait ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>: fn visit_embed_squash( self, embed: &'a E1, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(ExprF::Embed(self.visit_embed(embed)?)) } - - fn visit_note_squash( - mut self, - note: &'a N1, - subexpr: &'a SE1, - ) -> Result, Self::Error> { - let subexpr = self.visit_subexpr(subexpr)?; - let note = self.visit_note(note)?; - Ok(ExprF::Note(note, subexpr)) - } } -impl<'a, T, SE1, SE2, L1, L2, N1, N2, E1, E2> - ExprFVeryGenericVisitor<'a, ExprF, SE1, L1, N1, E1> for T +impl<'a, T, SE1, SE2, L1, L2, E1, E2> + ExprFVeryGenericVisitor<'a, ExprF, SE1, L1, E1> for T where - T: ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>, + T: ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>, { type Error = T::Error; type SE2 = SE2; type L2 = L2; - type N2 = N2; type E2 = E2; fn visit_subexpr( @@ -259,34 +237,23 @@ where fn visit_embed_squash( self, embed: &'a E1, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { self.visit_embed_squash(embed) } - fn visit_note_squash( - self, - note: &'a N1, - subexpr: &'a SE1, - ) -> Result, Self::Error> { - self.visit_note_squash(note, subexpr) - } - - // Called with the result of the map, in the non-embed/note case. + // 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, N1, N2, E1, E2>: - Sized -{ +pub trait ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>: Sized { fn visit_subexpr(&mut self, subexpr: &'a SE1) -> SE2; fn visit_label(&mut self, label: &'a L1) -> L2; - fn visit_note(self, note: &'a N1) -> N2; fn visit_embed(self, embed: &'a E1) -> E2; fn visit_subexpr_under_binder( @@ -304,28 +271,17 @@ pub trait ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>: ) } - fn visit_embed_squash(self, embed: &'a E1) -> ExprF { + fn visit_embed_squash(self, embed: &'a E1) -> ExprF { ExprF::Embed(self.visit_embed(embed)) } - - fn visit_note_squash( - mut self, - note: &'a N1, - subexpr: &'a SE1, - ) -> ExprF { - let subexpr = self.visit_subexpr(subexpr); - let note = self.visit_note(note); - ExprF::Note(note, subexpr) - } } struct InfallibleWrapper(T); -impl<'a, T, SE1, SE2, L1, L2, N1, N2, E1, E2> - ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2> - for InfallibleWrapper +impl<'a, T, SE1, SE2, L1, L2, E1, E2> + ExprFFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2> for InfallibleWrapper where - T: ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>, + T: ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>, { type Error = X; @@ -335,9 +291,6 @@ where fn visit_label(&mut self, label: &'a L1) -> Result { Ok(self.0.visit_label(label)) } - fn visit_note(self, note: &'a N1) -> Result { - Ok(self.0.visit_note(note)) - } fn visit_embed(self, embed: &'a E1) -> Result { Ok(self.0.visit_embed(embed)) } @@ -353,55 +306,41 @@ where fn visit_embed_squash( self, embed: &'a E1, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(self.0.visit_embed_squash(embed)) } - - fn visit_note_squash( - self, - note: &'a N1, - subexpr: &'a SE1, - ) -> Result, Self::Error> { - Ok(self.0.visit_note_squash(note, subexpr)) - } } -impl<'a, T, SE1, SE2, L1, L2, N1, N2, E1, E2> - GenericVisitor<&'a ExprF, ExprF> for T +impl<'a, T, SE1, SE2, L1, L2, E1, E2> + GenericVisitor<&'a ExprF, ExprF> for T where L1: Ord, L2: Ord, - T: ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, N1, N2, E1, E2>, + T: ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, 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_note: F3, pub visit_embed: F4, pub visit_label: F5, } -impl<'a, SE, L, N, E, SE2, L2, N2, E2, Err, F1, F2, F3, F4, F5> - ExprFFallibleVisitor<'a, SE, SE2, L, L2, N, N2, E, E2> - for TraverseRefWithBindersVisitor +impl<'a, SE, L, E, SE2, L2, E2, Err, F1, F2, F4, F5> + ExprFFallibleVisitor<'a, SE, SE2, L, L2, E, E2> + for TraverseRefWithBindersVisitor where SE: 'a, L: 'a, - N: 'a, E: 'a, L: Ord, L2: Ord, F1: FnMut(&'a SE) -> Result, F2: FnOnce(&'a L, &'a SE) -> Result, - F3: FnOnce(&'a N) -> Result, F4: FnOnce(&'a E) -> Result, F5: FnMut(&'a L) -> Result, { @@ -417,9 +356,6 @@ where ) -> Result { (self.visit_under_binder)(label, subexpr) } - fn visit_note(self, note: &'a N) -> Result { - (self.visit_note)(note) - } fn visit_embed(self, embed: &'a E) -> Result { (self.visit_embed)(embed) } @@ -428,25 +364,22 @@ where } } -pub struct TraverseRefVisitor { +pub struct TraverseRefVisitor { pub visit_subexpr: F1, - pub visit_note: F2, pub visit_embed: F3, pub visit_label: F4, } -impl<'a, SE, L, N, E, SE2, L2, N2, E2, Err, F1, F2, F3, F4> - ExprFFallibleVisitor<'a, SE, SE2, L, L2, N, N2, E, E2> - for TraverseRefVisitor +impl<'a, SE, L, E, SE2, L2, E2, Err, F1, F3, F4> + ExprFFallibleVisitor<'a, SE, SE2, L, L2, E, E2> + for TraverseRefVisitor where SE: 'a, L: 'a, - N: 'a, E: 'a, L: Ord, L2: Ord, F1: FnMut(&'a SE) -> Result, - F2: FnOnce(&'a N) -> Result, F3: FnOnce(&'a E) -> Result, F4: FnMut(&'a L) -> Result, { @@ -455,9 +388,6 @@ where fn visit_subexpr(&mut self, subexpr: &'a SE) -> Result { (self.visit_subexpr)(subexpr) } - fn visit_note(self, note: &'a N) -> Result { - (self.visit_note)(note) - } fn visit_embed(self, embed: &'a E) -> Result { (self.visit_embed)(embed) } @@ -469,17 +399,8 @@ where pub struct TraverseEmbedVisitor(pub F1); impl<'a, 'b, N, E, E2, Err, F1> - ExprFFallibleVisitor< - 'a, - SubExpr, - SubExpr, - Label, - Label, - N, - N, - E, - E2, - > for &'b mut TraverseEmbedVisitor + ExprFFallibleVisitor<'a, SubExpr, SubExpr, Label, Label, E, E2> + for &'b mut TraverseEmbedVisitor where N: Clone + 'a, F1: FnMut(&E) -> Result, @@ -492,9 +413,6 @@ where ) -> Result, Self::Error> { Ok(rc(subexpr.as_ref().visit(&mut **self)?)) } - fn visit_note(self, note: &'a N) -> Result { - Ok(N::clone(note)) - } fn visit_embed(self, embed: &'a E) -> Result { (self.0)(embed) } @@ -506,7 +424,7 @@ where pub struct SquashEmbedVisitor(pub F1); impl<'a, 'b, N, E1, E2, F1> - ExprFVeryGenericVisitor<'a, SubExpr, SubExpr, Label, N, E1> + ExprFVeryGenericVisitor<'a, SubExpr, SubExpr, Label, E1> for &'b mut SquashEmbedVisitor where N: Clone + 'a, @@ -515,7 +433,6 @@ where type Error = X; type SE2 = SubExpr; type L2 = Label; - type N2 = N; type E2 = E2; fn visit_subexpr( @@ -547,20 +464,10 @@ where Ok((self.0)(embed)) } - 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. + // 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, Self::Error> { Ok(rc(result)) } @@ -569,33 +476,14 @@ where pub struct UnNoteVisitor; impl<'a, 'b, N, E> - ExprFInFallibleVisitor< - 'a, - SubExpr, - SubExpr, - Label, - Label, - N, - X, - E, - E, - > for &'b mut UnNoteVisitor + ExprFInFallibleVisitor<'a, SubExpr, SubExpr, Label, Label, E, E> + for &'b mut UnNoteVisitor where E: Clone + 'a, { fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { rc(subexpr.as_ref().visit(&mut **self)) } - fn visit_note(self, _: &'a N) -> X { - unreachable!() - } - fn visit_note_squash( - self, - _: &'a N, - subexpr: &'a SubExpr, - ) -> Expr { - subexpr.as_ref().visit(self) - } fn visit_embed(self, embed: &'a E) -> E { E::clone(embed) } @@ -607,26 +495,14 @@ where pub struct NoteAbsurdVisitor; impl<'a, 'b, N, E> - ExprFInFallibleVisitor< - 'a, - SubExpr, - SubExpr, - Label, - Label, - X, - N, - E, - E, - > for &'b mut NoteAbsurdVisitor + ExprFInFallibleVisitor<'a, SubExpr, SubExpr, Label, Label, E, E> + for &'b mut NoteAbsurdVisitor where E: Clone + 'a, { fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { rc(subexpr.as_ref().visit(&mut **self)) } - fn visit_note(self, note: &'a X) -> N { - match *note {} - } fn visit_embed(self, embed: &'a E) -> E { E::clone(embed) } @@ -638,26 +514,14 @@ where pub struct EmbedAbsurdVisitor; impl<'a, 'b, N, E> - ExprFInFallibleVisitor< - 'a, - SubExpr, - SubExpr, - Label, - Label, - N, - N, - X, - E, - > for &'b mut EmbedAbsurdVisitor + ExprFInFallibleVisitor<'a, SubExpr, SubExpr, Label, Label, X, E> + for &'b mut EmbedAbsurdVisitor where N: Clone + 'a, { fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { rc(subexpr.as_ref().visit(&mut **self)) } - fn visit_note(self, note: &'a N) -> N { - N::clone(note) - } fn visit_embed(self, embed: &'a X) -> E { match *embed {} } -- cgit v1.2.3