From 2ec0dc3f470be85a093caf1ebaa8898576c8c478 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 17 Mar 2019 22:35:05 +0100 Subject: Clean up some mess relating to Clone bounds --- dhall/src/normalize.rs | 22 ++++++------- dhall/src/typecheck.rs | 4 +-- dhall_core/src/core.rs | 84 +++++++++++++----------------------------------- dhall_core/src/parser.rs | 14 ++++---- 4 files changed, 43 insertions(+), 81 deletions(-) diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs index fccc938..af30e3b 100644 --- a/dhall/src/normalize.rs +++ b/dhall/src/normalize.rs @@ -11,8 +11,8 @@ use std::rc::Rc; /// This allows normalization to be lazy. pub fn normalize_whnf(e: &SubExpr) -> SubExpr where - S: Clone + fmt::Debug, - A: Clone + fmt::Debug, + S: fmt::Debug, + A: fmt::Debug, { use dhall_core::BinOp::*; use dhall_core::Builtin::*; @@ -20,9 +20,9 @@ where rc(match e.as_ref() { Let(f, _, r, b) => { let vf0 = &V(f.clone(), 0); - let r2 = shift::<_, S, _>(1, vf0, r); - let b2 = subst::<_, S, _>(vf0, &r2, b); - let b3 = shift::<_, S, _>(-1, vf0, &b2); + let r2 = shift(1, vf0, r); + let b2 = subst(vf0, &r2, b); + let b3 = shift(-1, vf0, &b2); return normalize_whnf(&b3); } Annot(x, _) => return normalize_whnf(x), @@ -40,9 +40,9 @@ where (Lam(ref x, _, ref b), [a, rest..]) => { // Beta reduce let vx0 = &V(x.clone(), 0); - let a2 = shift::(1, vx0, a); - let b2 = subst::(vx0, &a2, &b); - let b3 = shift::(-1, vx0, &b2); + let a2 = shift(1, vx0, a); + let b2 = subst(vx0, &a2, &b); + let b3 = shift(-1, vx0, &b2); return normalize_whnf(&rc(App(b3, rest.to_vec()))); } // TODO: this is more normalization than needed @@ -165,8 +165,8 @@ where } ( OptionalFold, - [_, OptionalLit(_, None), _, _, nothing], - ) => (*nothing).clone(), + [_, OptionalLit(_, None), _, _, _], + ) => return Rc::clone(&args[4]), // // fold/build fusion // (OptionalFold, [_, App(box Builtin(OptionalBuild), [_, x, rest..]), rest..]) => { // normalize_whnf(&App(bx(x.clone()), rest.to_vec())) @@ -238,7 +238,7 @@ where } // TODO: interpolation (TextAppend, TextLit(x), TextLit(y)) => { - TextLit(x.clone() + y.clone()) + TextLit(x + y) } (ListAppend, ListLit(t1, xs), ListLit(t2, ys)) => { let t1: Option> = t1.as_ref().map(Rc::clone); diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index d6195a5..b507e52 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -260,9 +260,9 @@ where let tA2 = type_with(ctx, a.clone())?; if prop_equal(tA.clone(), tA2.clone()) { let vx0 = &V(x.clone(), 0); - let a2 = shift::(1, vx0, a); + let a2 = shift(1, vx0, a); let tB2 = subst(vx0, &a2, &tB); - let tB3 = shift::(-1, vx0, &tB2); + let tB3 = shift(-1, vx0, &tB2); return Ok(tB3); } else { let nf_A = normalize(tA.clone()); diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index eba6a42..51356cf 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -199,33 +199,9 @@ impl From for InterpolatedText { } } -// TODO: merge both when we move to Rc<> -// This one is needed when parsing, because we need to own the Expr -pub enum OwnedInterpolatedTextContents<'a, Note, Embed> { +pub enum InterpolatedTextContents<'a, Note, Embed> { Text(&'a str), - Expr(Rc>), -} - -// This one is needed everywhere else, because we don't want Clone traits bounds -// everywhere -pub enum BorrowedInterpolatedTextContents<'a, Note, Embed> { - Text(&'a str), - Expr(&'a Expr), -} - -impl<'a, N: Clone + 'a, E: Clone + 'a> - BorrowedInterpolatedTextContents<'a, N, E> -{ - pub fn to_owned(self) -> OwnedInterpolatedTextContents<'a, N, E> { - match self { - BorrowedInterpolatedTextContents::Text(s) => { - OwnedInterpolatedTextContents::Text(s) - } - BorrowedInterpolatedTextContents::Expr(e) => { - OwnedInterpolatedTextContents::Expr(bx(e.clone())) - } - } - } + Expr(SubExpr), } impl InterpolatedText { @@ -241,24 +217,24 @@ impl InterpolatedText { pub fn iter( &self, - ) -> impl Iterator> { + ) -> impl Iterator> { use std::iter::once; - once(BorrowedInterpolatedTextContents::Text(self.head.as_ref())).chain( + once(InterpolatedTextContents::Text(self.head.as_ref())).chain( self.tail.iter().flat_map(|(e, s)| { - once(BorrowedInterpolatedTextContents::Expr(e)) - .chain(once(BorrowedInterpolatedTextContents::Text(s))) + once(InterpolatedTextContents::Expr(Rc::clone(e))) + .chain(once(InterpolatedTextContents::Text(s))) }), ) } } -impl<'a, N: Clone + 'a, E: Clone + 'a> - FromIterator> +impl<'a, N: 'a, E: 'a> + FromIterator> for InterpolatedText { fn from_iter(iter: T) -> Self where - T: IntoIterator>, + T: IntoIterator>, { let mut res = InterpolatedText { head: "".to_owned(), @@ -268,8 +244,8 @@ impl<'a, N: Clone + 'a, E: Clone + 'a> let mut crnt_str = &mut res.head; for x in iter.into_iter() { match x { - OwnedInterpolatedTextContents::Text(s) => crnt_str.push_str(s), - OwnedInterpolatedTextContents::Expr(e) => { + InterpolatedTextContents::Text(s) => crnt_str.push_str(s), + InterpolatedTextContents::Expr(e) => { // crnt_str = &mut empty_string; res.tail.push((e.clone(), "".to_owned())); crnt_str = &mut res.tail.last_mut().unwrap().1; @@ -280,12 +256,11 @@ impl<'a, N: Clone + 'a, E: Clone + 'a> } } -impl Add for InterpolatedText { +impl Add for &InterpolatedText { type Output = InterpolatedText; - fn add(self, rhs: InterpolatedText) -> Self::Output { + fn add(self, rhs: &InterpolatedText) -> Self::Output { self.iter() .chain(rhs.iter()) - .map(BorrowedInterpolatedTextContents::to_owned) .collect() } } @@ -715,10 +690,10 @@ impl Expr { &TextLit(ref a) => { for x in a.iter() { match x { - BorrowedInterpolatedTextContents::Text(a) => { + InterpolatedTextContents::Text(a) => { ::fmt(a, f)? } // TODO Format escapes properly - BorrowedInterpolatedTextContents::Expr(e) => { + InterpolatedTextContents::Expr(e) => { f.write_str("${")?; e.fmt(f)?; f.write_str("}")?; @@ -1079,11 +1054,11 @@ where /// descend into a lambda or let expression that binds a variable of the same /// name in order to avoid shifting the bound variables by mistake. /// -pub fn shift( +pub fn shift( d: isize, v: &V, e: &Rc>, -) -> Rc> { +) -> Rc> { use crate::Expr::*; let V(x, n) = v; rc(match e.as_ref() { @@ -1160,7 +1135,7 @@ pub fn shift( Note(_, b) => return shift(d, v, b), // The Dhall compiler enforces that all embedded values are closed expressions // and `shift` does nothing to a closed expression - Embed(p) => Embed(p.clone()), + Embed(_) => return Rc::clone(e), }) } @@ -1170,19 +1145,15 @@ pub fn shift( /// subst x C B ~ B[x := C] /// ``` /// -pub fn subst( +pub fn subst( v: &V, e: &Rc>, - b: &Rc>, + b: &Rc>, ) -> Rc> -where - S: Clone, - A: Clone, { use crate::Expr::*; let V(x, n) = v; rc(match b.as_ref() { - Const(a) => Const(*a), Lam(y, tA, b) => { let n2 = if x == y { n + 1 } else { *n }; let b2 = @@ -1202,12 +1173,8 @@ where let args = args.iter().map(|a| subst(v, e, a)).collect(); App(f2, args) } - Var(v2) => { - if v == v2 { - return e.clone(); - } else { - Var(v2.clone()) - } + Var(v2) if v == v2 => { + return e.clone(); } Let(f, mt, r, b) => { let n2 = if x == f { n + 1 } else { *n }; @@ -1218,17 +1185,12 @@ where Let(f.clone(), mt2, r2, b2) } Annot(a, b) => map_op2(Annot, |x| subst(v, e, x), a, b), - Builtin(v) => Builtin(*v), - BoolLit(a) => BoolLit(*a), BinOp(o, a, b) => { map_op2(|x, y| BinOp(*o, x, y), |x| subst(v, e, x), a, b) } BoolIf(a, b, c) => { BoolIf(subst(v, e, a), subst(v, e, b), subst(v, e, c)) } - NaturalLit(a) => NaturalLit(*a), - IntegerLit(a) => IntegerLit(*a), - DoubleLit(a) => DoubleLit(*a), TextLit(a) => TextLit(a.map(|b| subst(v, e, &*b))), ListLit(a, b) => { let a2 = a.as_ref().map(|a| subst(v, e, a)); @@ -1257,6 +1219,6 @@ where ), Field(a, b) => Field(subst(v, e, a), b.clone()), Note(_, b) => return subst(v, e, b), - Embed(p) => Embed(p.clone()), + _ => return Rc::clone(b), }) } diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index 682e081..9487ebc 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -16,7 +16,7 @@ use crate::core::*; pub type ParsedExpr = Expr; pub type ParsedText = InterpolatedText; -pub type ParsedTextContents<'a> = OwnedInterpolatedTextContents<'a, X, Import>; +pub type ParsedTextContents<'a> = InterpolatedTextContents<'a, X, Import>; pub type RcExpr = Rc; pub type ParseError = pest::error::Error; @@ -438,10 +438,10 @@ rule!(double_quote_literal; // TODO: parse escapes rule!(double_quote_chunk>; children!(c: interpolation) => { - OwnedInterpolatedTextContents::Expr(c) + InterpolatedTextContents::Expr(c) }, captured_str!(s) => { - OwnedInterpolatedTextContents::Text(s) + InterpolatedTextContents::Text(s) }, ); @@ -462,16 +462,16 @@ rule!(interpolation; rule!(single_quote_continue>>; children!(c: interpolation, rest: single_quote_continue) => { - rest.push(OwnedInterpolatedTextContents::Expr(c)); rest + rest.push(InterpolatedTextContents::Expr(c)); rest }, children!(c: escaped_quote_pair, rest: single_quote_continue) => { - rest.push(OwnedInterpolatedTextContents::Text(c)); rest + rest.push(InterpolatedTextContents::Text(c)); rest }, children!(c: escaped_interpolation, rest: single_quote_continue) => { - rest.push(OwnedInterpolatedTextContents::Text(c)); rest + rest.push(InterpolatedTextContents::Text(c)); rest }, children!(c: raw_str, rest: single_quote_continue) => { - rest.push(OwnedInterpolatedTextContents::Text(c)); rest + rest.push(InterpolatedTextContents::Text(c)); rest }, children!() => { vec![] -- cgit v1.2.3