From 7fe85bcd1ddecf58814e35f02cab8ef652a1e9c2 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Fri, 8 Sep 2017 23:48:29 +0200 Subject: fixed some clippy warnings --- src/context.rs | 4 +- src/core.rs | 240 +++++++++++++++++++++++++++---------------------------- src/lexer.rs | 2 +- src/main.rs | 6 +- src/typecheck.rs | 123 ++++++++++++++-------------- 5 files changed, 187 insertions(+), 188 deletions(-) (limited to 'src') diff --git a/src/context.rs b/src/context.rs index 9fb3bf4..c2e1913 100644 --- a/src/context.rs +++ b/src/context.rs @@ -34,7 +34,7 @@ impl<'i, T> Context<'i, T> { } pub fn map U>(&self, f: F) -> Context<'i, U> { - Context(self.0.iter().map(|(k, v)| (k.clone(), v.iter().map(&f).collect())).collect()) + Context(self.0.iter().map(|(k, v)| (*k, v.iter().map(&f).collect())).collect()) } } @@ -43,7 +43,7 @@ impl<'i, T: Clone> Context<'i, T> { pub fn insert(&self, k: &'i str, v: T) -> Self { let mut ctx = (*self).clone(); { - let m = ctx.0.entry(k).or_insert(vec![]); + let m = ctx.0.entry(k).or_insert_with(Vec::new); m.push(v); } ctx diff --git a/src/core.rs b/src/core.rs index 02ff6ac..a9de523 100644 --- a/src/core.rs +++ b/src/core.rs @@ -257,22 +257,22 @@ impl<'i, S, A> From for Expr<'i, S, A> { impl<'i, S, A> Expr<'i, S, A> { fn bool_lit(&self) -> Option { - match self { - &Expr::BoolLit(v) => Some(v), + match *self { + Expr::BoolLit(v) => Some(v), _ => None, } } fn natural_lit(&self) -> Option { - match self { - &Expr::NaturalLit(v) => Some(v), + match *self { + Expr::NaturalLit(v) => Some(v), _ => None, } } fn text_lit(&self) -> Option { - match self { - &Expr::TextLit(ref t) => Some(t.clone()), // FIXME? + match *self { + Expr::TextLit(ref t) => Some(t.clone()), // FIXME? _ => None, } } @@ -423,7 +423,7 @@ impl<'i, S, A: Display> Expr<'i, S, A> { fmt_list("{ ", " }", a, f, |(k, v), f| write!(f, "{} = {}", k, v)) } &Union(ref _a) => f.write_str("Union"), - &UnionLit(ref _a, ref _b, ref _c) => f.write_str("UnionLit"), + &UnionLit(_a, ref _b, ref _c) => f.write_str("UnionLit"), &Embed(ref a) => a.fmt(f), &Note(_, ref b) => b.fmt_f(f), a => write!(f, "({})", a), @@ -531,7 +531,7 @@ pub fn bx(x: T) -> Box { fn add_ui(u: usize, i: isize) -> usize { if i < 0 { - u.checked_sub((i.checked_neg().unwrap() as usize)).unwrap() + u.checked_sub(i.checked_neg().unwrap() as usize).unwrap() } else { u.checked_add(i as usize).unwrap() } @@ -627,75 +627,75 @@ fn map_op2(f: F, g: G, a: T, b: T) -> V pub fn shift<'i, S, T, A: Clone>(d: isize, v: V, e: &Expr<'i, S, A>) -> Expr<'i, T, A> { use Expr::*; let V(x, n) = v; - match e { - &Const(a) => Const(a), - &Var(V(x2, n2)) => { + match *e { + Const(a) => Const(a), + Var(V(x2, n2)) => { let n3 = if x == x2 && n <= n2 { add_ui(n2, d) } else { n2 }; Var(V(x2, n3)) } - &Lam(x2, ref tA, ref b) => { + Lam(x2, ref tA, ref b) => { let n2 = if x == x2 { n + 1 } else { n }; let tA2 = shift(d, V(x, n ), tA); let b2 = shift(d, V(x, n2), b); Lam(x2, bx(tA2), bx(b2)) } - &Pi(x2, ref tA, ref tB) => { + Pi(x2, ref tA, ref tB) => { let n2 = if x == x2 { n + 1 } else { n }; let tA2 = shift(d, V(x, n ), tA); let tB2 = shift(d, V(x, n2), tB); pi(x2, tA2, tB2) } - &App(ref f, ref a) => app(shift(d, v, f), shift(d, v, a)), - &Let(f, ref mt, ref r, ref e) => { + App(ref f, ref a) => app(shift(d, v, f), shift(d, v, a)), + Let(f, ref mt, ref r, ref e) => { let n2 = if x == f { n + 1 } else { n }; let e2 = shift(d, V(x, n2), e); let mt2 = mt.as_ref().map(|t| bx(shift(d, V(x, n), t))); let r2 = shift(d, V(x, n), r); Let(f, mt2, bx(r2), bx(e2)) } - &Annot(ref a, ref b) => shift_op2(Annot, d, v, a, b), - &BuiltinType(t) => BuiltinType(t), - &BuiltinValue(v) => BuiltinValue(v), - &BoolLit(a) => BoolLit(a), - &BoolAnd(ref a, ref b) => shift_op2(BoolAnd, d, v, a, b), - &BoolOr(ref a, ref b) => shift_op2(BoolOr, d, v, a, b), - &BoolEQ(ref a, ref b) => shift_op2(BoolEQ, d, v, a, b), - &BoolNE(ref a, ref b) => shift_op2(BoolNE, d, v, a, b), - &BoolIf(ref a, ref b, ref c) => { + Annot(ref a, ref b) => shift_op2(Annot, d, v, a, b), + BuiltinType(t) => BuiltinType(t), + BuiltinValue(v) => BuiltinValue(v), + BoolLit(a) => BoolLit(a), + BoolAnd(ref a, ref b) => shift_op2(BoolAnd, d, v, a, b), + BoolOr(ref a, ref b) => shift_op2(BoolOr, d, v, a, b), + BoolEQ(ref a, ref b) => shift_op2(BoolEQ, d, v, a, b), + BoolNE(ref a, ref b) => shift_op2(BoolNE, d, v, a, b), + BoolIf(ref a, ref b, ref c) => { BoolIf(bx(shift(d, v, a)), bx(shift(d, v, b)), bx(shift(d, v, c))) } - &NaturalLit(a) => NaturalLit(a), - &NaturalPlus(ref a, ref b) => NaturalPlus(bx(shift(d, v, a)), bx(shift(d, v, b))), - &NaturalTimes(ref a, ref b) => shift_op2(NaturalTimes, d, v, a, b), - &IntegerLit(a) => IntegerLit(a), - &DoubleLit(a) => DoubleLit(a), - &TextLit(ref a) => TextLit(a.clone()), - &TextAppend(ref a, ref b) => shift_op2(TextAppend, d, v, a, b), - &ListLit(ref t, ref es) => { + NaturalLit(a) => NaturalLit(a), + NaturalPlus(ref a, ref b) => NaturalPlus(bx(shift(d, v, a)), bx(shift(d, v, b))), + NaturalTimes(ref a, ref b) => shift_op2(NaturalTimes, d, v, a, b), + IntegerLit(a) => IntegerLit(a), + DoubleLit(a) => DoubleLit(a), + TextLit(ref a) => TextLit(a.clone()), + TextAppend(ref a, ref b) => shift_op2(TextAppend, d, v, a, b), + ListLit(ref t, ref es) => { ListLit(bx(shift(d, v, t)), es.iter().map(|e| shift(d, v, e)).collect()) } - &OptionalLit(ref t, ref es) => { + OptionalLit(ref t, ref es) => { OptionalLit(bx(shift(d, v, t)), es.iter().map(|e| shift(d, v, e)).collect()) } - &Record(ref a) => Record(map_record_value(a, |val| shift(d, v, val))), - &RecordLit(ref a) => RecordLit(map_record_value(a, |val| shift(d, v, val))), - &Union(ref a) => Union(map_record_value(a, |val| shift(d, v, val))), - &UnionLit(k, ref uv, ref a) => { + Record(ref a) => Record(map_record_value(a, |val| shift(d, v, val))), + RecordLit(ref a) => RecordLit(map_record_value(a, |val| shift(d, v, val))), + Union(ref a) => Union(map_record_value(a, |val| shift(d, v, val))), + UnionLit(k, ref uv, ref a) => { UnionLit(k, bx(shift(d, v, uv)), map_record_value(a, |val| shift(d, v, val))) } - &Combine(ref a, ref b) => shift_op2(Combine, d, v, a, b), - &Merge(ref a, ref b, ref c) => { + Combine(ref a, ref b) => shift_op2(Combine, d, v, a, b), + Merge(ref a, ref b, ref c) => { Merge(bx(shift(d, v, a)), bx(shift(d, v, b)), bx(shift(d, v, c))) } - &Field(ref a, b) => Field(bx(shift(d, v, a)), b), - &Note(_, ref b) => shift(d, v, b), + Field(ref a, b) => Field(bx(shift(d, v, a)), b), + Note(_, ref b) => shift(d, v, b), // The Dhall compiler enforces that all embedded values are closed expressions // and `shift` does nothing to a closed expression - &Embed(ref p) => Embed(p.clone()), + Embed(ref p) => Embed(p.clone()), } } @@ -723,76 +723,76 @@ pub fn subst<'i, S, T, A>(v: V<'i>, e: &Expr<'i, S, A>, b: &Expr<'i, T, A>) -> E { use Expr::*; let V(x, n) = v; - match b { - &Const(a) => Const(a), - &Lam(y, ref tA, ref b) => { + match *b { + Const(a) => Const(a), + Lam(y, ref tA, ref b) => { let n2 = if x == y { n + 1 } else { n }; - let b2 = subst(V(x, n2), &shift(1, V(y, 0), &e), b); - let tA2 = subst(V(x, n), &e, tA); + let b2 = subst(V(x, n2), &shift(1, V(y, 0), e), b); + let tA2 = subst(V(x, n), e, tA); Lam(y, bx(tA2), bx(b2)) } - &Pi(y, ref tA, ref tB) => { + Pi(y, ref tA, ref tB) => { let n2 = if x == y { n + 1 } else { n }; - let tB2 = subst(V(x, n2), &shift(1, V(y, 0), &e), tB); - let tA2 = subst(V(x, n), &e, tA); + let tB2 = subst(V(x, n2), &shift(1, V(y, 0), e), tB); + let tA2 = subst(V(x, n), e, tA); pi(y, tA2, tB2) } - &App(ref f, ref a) => { + App(ref f, ref a) => { let f2 = subst(v, e, f); let a2 = subst(v, e, a); app(f2, a2) } - &Var(v2) => if v == v2 { e.clone() } else { Var(v2) }, - &Let(f, ref mt, ref r, ref b) => { + Var(v2) => if v == v2 { e.clone() } else { Var(v2) }, + Let(f, ref mt, ref r, ref b) => { let n2 = if x == f { n + 1 } else { n }; let b2 = subst(V(x, n2), &shift(1, V(f, 0), e), b); let mt2 = mt.as_ref().map(|t| bx(subst(V(x, n), e, t))); let r2 = subst(V(x, n), e, r); Let(f, mt2, bx(r2), bx(b2)) } - &Annot(ref a, ref b) => subst_op2(Annot, v, e, a, b), - &BuiltinType(t) => BuiltinType(t), - &BuiltinValue(v) => BuiltinValue(v), - &BoolLit(a) => BoolLit(a), - &BoolAnd(ref a, ref b) => subst_op2(BoolAnd, v, e, a, b), - &BoolOr(ref a, ref b) => subst_op2(BoolOr, v, e, a, b), - &BoolEQ(ref a, ref b) => subst_op2(BoolEQ, v, e, a, b), - &BoolNE(ref a, ref b) => subst_op2(BoolNE, v, e, a, b), - &BoolIf(ref a, ref b, ref c) => { + Annot(ref a, ref b) => subst_op2(Annot, v, e, a, b), + BuiltinType(t) => BuiltinType(t), + BuiltinValue(v) => BuiltinValue(v), + BoolLit(a) => BoolLit(a), + BoolAnd(ref a, ref b) => subst_op2(BoolAnd, v, e, a, b), + BoolOr(ref a, ref b) => subst_op2(BoolOr, v, e, a, b), + BoolEQ(ref a, ref b) => subst_op2(BoolEQ, v, e, a, b), + BoolNE(ref a, ref b) => subst_op2(BoolNE, v, e, a, b), + BoolIf(ref a, ref b, ref c) => { BoolIf(bx(subst(v, e, a)), bx(subst(v, e, b)), bx(subst(v, e, c))) } - &NaturalLit(a) => NaturalLit(a), - &NaturalPlus(ref a, ref b) => subst_op2(NaturalPlus, v, e, a, b), - &NaturalTimes(ref a, ref b) => subst_op2(NaturalTimes, v, e, a, b), - &IntegerLit(a) => IntegerLit(a), - &DoubleLit(a) => DoubleLit(a), - &TextLit(ref a) => TextLit(a.clone()), - &TextAppend(ref a, ref b) => subst_op2(TextAppend, v, e, a, b), - &ListLit(ref a, ref b) => { + NaturalLit(a) => NaturalLit(a), + NaturalPlus(ref a, ref b) => subst_op2(NaturalPlus, v, e, a, b), + NaturalTimes(ref a, ref b) => subst_op2(NaturalTimes, v, e, a, b), + IntegerLit(a) => IntegerLit(a), + DoubleLit(a) => DoubleLit(a), + TextLit(ref a) => TextLit(a.clone()), + TextAppend(ref a, ref b) => subst_op2(TextAppend, v, e, a, b), + ListLit(ref a, ref b) => { let a2 = subst(v, e, a); let b2 = b.iter().map(|be| subst(v, e, be)).collect(); ListLit(bx(a2), b2) } - &OptionalLit(ref a, ref b) => { + OptionalLit(ref a, ref b) => { let a2 = subst(v, e, a); let b2 = b.iter().map(|be| subst(v, e, be)).collect(); OptionalLit(bx(a2), b2) } - &Record(ref kts) => Record(map_record_value(kts, |t| subst(v, e, t))), - &RecordLit(ref kvs) => RecordLit(map_record_value(kvs, |val| subst(v, e, val))), - &Union(ref kts) => Union(map_record_value(kts, |t| subst(v, e, t))), - &UnionLit(k, ref uv, ref kvs) => { + Record(ref kts) => Record(map_record_value(kts, |t| subst(v, e, t))), + RecordLit(ref kvs) => RecordLit(map_record_value(kvs, |val| subst(v, e, val))), + Union(ref kts) => Union(map_record_value(kts, |t| subst(v, e, t))), + UnionLit(k, ref uv, ref kvs) => { UnionLit(k, bx(subst(v, e, uv)), map_record_value(kvs, |val| subst(v, e, val))) } - &Combine(ref a, ref b) => subst_op2(Combine, v, e, a, b), - &Merge(ref a, ref b, ref c) => { + Combine(ref a, ref b) => subst_op2(Combine, v, e, a, b), + Merge(ref a, ref b, ref c) => { Merge(bx(subst(v, e, a)), bx(subst(v, e, b)), bx(subst(v, e, c))) } - &Field(ref a, b) => Field(bx(subst(v, e, a)), b), - &Note(_, ref b) => subst(v, e, b), - &Embed(ref p) => Embed(p.clone()), + Field(ref a, b) => Field(bx(subst(v, e, a)), b), + Note(_, ref b) => subst(v, e, b), + Embed(ref p) => Embed(p.clone()), } } @@ -825,20 +825,20 @@ pub fn normalize<'i, S, T, A>(e: &Expr<'i, S, A>) -> Expr<'i, T, A> { use BuiltinValue::*; use Expr::*; - match e { - &Const(k) => Const(k), - &Var(v) => Var(v), - &Lam(x, ref tA, ref b) => { + match *e { + Const(k) => Const(k), + Var(v) => Var(v), + Lam(x, ref tA, ref b) => { let tA2 = normalize(tA); let b2 = normalize(b); Lam(x, bx(tA2), bx(b2)) } - &Pi(x, ref tA, ref tB) => { + Pi(x, ref tA, ref tB) => { let tA2 = normalize(tA); let tB2 = normalize(tB); pi(x, tA2, tB2) } - &App(ref f, ref a) => match normalize::(f) { + App(ref f, ref a) => match normalize::(f) { Lam(x, _A, b) => { // Beta reduce let vx0 = V(x, 0); let a2 = shift::( 1, vx0, a); @@ -848,11 +848,11 @@ pub fn normalize<'i, S, T, A>(e: &Expr<'i, S, A>) -> Expr<'i, T, A> } f2 => match (f2, normalize::(a)) { // fold/build fusion for `List` - (App(box BuiltinValue(ListBuild), _), App(box App(box BuiltinValue(ListFold), _), box e2)) => normalize(&e2), - (App(box BuiltinValue(ListFold), _), App(box App(box BuiltinValue(ListBuild), _), box e2)) => normalize(&e2), + (App(box BuiltinValue(ListBuild), _), App(box App(box BuiltinValue(ListFold), _), box e2)) | + (App(box BuiltinValue(ListFold), _), App(box App(box BuiltinValue(ListBuild), _), box e2)) | // fold/build fusion for `Natural` - (BuiltinValue(NaturalBuild), App(box BuiltinValue(NaturalFold), box e2)) => normalize(&e2), + (BuiltinValue(NaturalBuild), App(box BuiltinValue(NaturalFold), box e2)) | (BuiltinValue(NaturalFold), App(box BuiltinValue(NaturalBuild), box e2)) => normalize(&e2), /* @@ -900,9 +900,9 @@ pub fn normalize<'i, S, T, A>(e: &Expr<'i, S, A>) -> Expr<'i, T, A> } } fn check(e: &Expr) -> bool { - match e { - &App(box App(box Var(V("Cons", _)), _), ref e2) => check(e2), - &Var(V("Nil", _)) => true, + match *e { + App(box App(box Var(V("Cons", _)), _), ref e2) => check(e2), + Var(V("Nil", _)) => true, _ => false, } } @@ -958,85 +958,85 @@ pub fn normalize<'i, S, T, A>(e: &Expr<'i, S, A>) -> Expr<'i, T, A> (f2, a2) => app(f2, a2), } }, - &Let(f, _, ref r, ref b) => { + Let(f, _, ref r, ref b) => { let r2 = shift::<_, S, _>( 1, V(f, 0), r); let b2 = subst(V(f, 0), &r2, b); let b3 = shift::<_, T, _>(-1, V(f, 0), &b2); normalize(&b3) } - &Annot(ref x, _) => normalize(x), - &BuiltinType(t) => BuiltinType(t), - &BuiltinValue(v) => BuiltinValue(v), - &BoolLit(b) => BoolLit(b), - &BoolAnd(ref x, ref y) => { + Annot(ref x, _) => normalize(x), + BuiltinType(t) => BuiltinType(t), + BuiltinValue(v) => BuiltinValue(v), + BoolLit(b) => BoolLit(b), + BoolAnd(ref x, ref y) => { with_binop(BoolAnd, Expr::bool_lit, |xn, yn| BoolLit(xn && yn), normalize(x), normalize(y)) } - &BoolOr(ref x, ref y) => { + BoolOr(ref x, ref y) => { with_binop(BoolOr, Expr::bool_lit, |xn, yn| BoolLit(xn || yn), normalize(x), normalize(y)) } - &BoolEQ(ref x, ref y) => { + BoolEQ(ref x, ref y) => { with_binop(BoolEQ, Expr::bool_lit, |xn, yn| BoolLit(xn == yn), normalize(x), normalize(y)) } - &BoolNE(ref x, ref y) => { + BoolNE(ref x, ref y) => { with_binop(BoolNE, Expr::bool_lit, |xn, yn| BoolLit(xn != yn), normalize(x), normalize(y)) } - &BoolIf(ref b, ref t, ref f) => match normalize(b) { + BoolIf(ref b, ref t, ref f) => match normalize(b) { BoolLit(true) => normalize(t), BoolLit(false) => normalize(f), b2 => BoolIf(bx(b2), bx(normalize(t)), bx(normalize(f))), }, - &NaturalLit(n) => NaturalLit(n), - &NaturalPlus(ref x, ref y) => { + NaturalLit(n) => NaturalLit(n), + NaturalPlus(ref x, ref y) => { with_binop(NaturalPlus, Expr::natural_lit, |xn, yn| NaturalLit(xn + yn), normalize(x), normalize(y)) } - &NaturalTimes(ref x, ref y) => { + NaturalTimes(ref x, ref y) => { with_binop(NaturalTimes, Expr::natural_lit, |xn, yn| NaturalLit(xn * yn), normalize(x), normalize(y)) } - &IntegerLit(n) => IntegerLit(n), - &DoubleLit(n) => DoubleLit(n), - &TextLit(ref t) => TextLit(t.clone()), - &TextAppend(ref x, ref y) => { + IntegerLit(n) => IntegerLit(n), + DoubleLit(n) => DoubleLit(n), + TextLit(ref t) => TextLit(t.clone()), + TextAppend(ref x, ref y) => { with_binop(TextAppend, Expr::text_lit, |xt, yt| TextLit(xt + &yt), normalize(x), normalize(y)) } - &ListLit(ref t, ref es) => { + ListLit(ref t, ref es) => { let t2 = normalize(t); let es2 = es.iter().map(normalize).collect(); ListLit(bx(t2), es2) } - &OptionalLit(ref t, ref es) => { + OptionalLit(ref t, ref es) => { let t2 = normalize(t); let es2 = es.iter().map(normalize).collect(); OptionalLit(bx(t2), es2) } - &Record(ref kts) => Record(map_record_value(kts, normalize)), - &RecordLit(ref kvs) => RecordLit(map_record_value(kvs, normalize)), - &Union(ref kts) => Union(map_record_value(kts, normalize)), - &UnionLit(k, ref v, ref kvs) => UnionLit(k, bx(normalize(v)), map_record_value(kvs, normalize)), - &Combine(ref _x0, ref _y0) => unimplemented!(), - &Merge(ref _x, ref _y, ref _t) => unimplemented!(), - &Field(ref r, x) => match normalize(r) { + Record(ref kts) => Record(map_record_value(kts, normalize)), + RecordLit(ref kvs) => RecordLit(map_record_value(kvs, normalize)), + Union(ref kts) => Union(map_record_value(kts, normalize)), + UnionLit(k, ref v, ref kvs) => UnionLit(k, bx(normalize(v)), map_record_value(kvs, normalize)), + Combine(ref _x0, ref _y0) => unimplemented!(), + Merge(ref _x, ref _y, ref _t) => unimplemented!(), + Field(ref r, x) => match normalize(r) { RecordLit(kvs) => match kvs.get(x) { Some(r2) => normalize(r2), None => Field(bx(RecordLit(map_record_value(&kvs, normalize))), x), }, r2 => Field(bx(r2), x), }, - &Note(_, ref e) => normalize(e), - &Embed(ref a) => Embed(a.clone()), + Note(_, ref e) => normalize(e), + Embed(ref a) => Embed(a.clone()), } } diff --git a/src/lexer.rs b/src/lexer.rs index 2a7e44b..bc96040 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -328,7 +328,7 @@ impl<'input> Iterator for Lexer<'input> { use nom::IResult::*; self.skip_comments_and_whitespace(); let input = self.current_input(); - if input.len() == 0 { + if input.is_empty() { return None; } match token(input) { diff --git a/src/main.rs b/src/main.rs index d4b541b..9f7e2e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ const ERROR_STYLE: term_painter::Color = term_painter::Color::Red; const BOLD: term_painter::Attr = term_painter::Attr::Bold; fn print_error(message: &str, source: &str, start: usize, end: usize) { - let line_number = bytecount::count(source[..start].as_bytes(), '\n' as u8); + let line_number = bytecount::count(source[..start].as_bytes(), b'\n'); let line_start = source[..start].rfind('\n').map(|i| i + 1).unwrap_or(0); let line_end = source[end..].find('\n').unwrap_or(0) + end; let context_prefix = &source[line_start..start]; @@ -76,7 +76,7 @@ fn main() { } Err(lalrpop_util::ParseError::UnrecognizedToken { token: Some((start, t, end)), expected: e }) => { print_error(&format!("Unrecognized token {:?}", t), &buffer, start, end); - if e.len() > 0 { + if !e.is_empty() { println!("Expected {:?}", e); } return; @@ -93,7 +93,7 @@ fn main() { let type_expr = match typecheck::type_of(&expr) { Err(e) => { - let explain = ::std::env::args().find(|s| s == "--explain").is_some(); + let explain = ::std::env::args().any(|s| s == "--explain"); if !explain { term_painter::Color::BrightBlack.with(|| { println!("Use \"dhall --explain\" for detailed errors"); diff --git a/src/typecheck.rs b/src/typecheck.rs index 39caa7e..576b059 100644 --- a/src/typecheck.rs +++ b/src/typecheck.rs @@ -24,8 +24,8 @@ fn axiom<'i, S: Clone>(c: core::Const) -> Result> fn rule(a: core::Const, b: core::Const) -> Result { match (a, b) { (Type, Kind) => Err(()), - (Type, Type) => Ok(Type), (Kind, Kind) => Ok(Kind), + (Type, Type) | (Kind, Type) => Ok(Type), } } @@ -52,10 +52,10 @@ fn prop_equal(eL0: &Expr, eR0: &Expr) -> bool T: Clone + ::std::fmt::Debug { match (el, er) { - (&Const(Type), &Const(Type)) => true, + (&Const(Type), &Const(Type)) | (&Const(Kind), &Const(Kind)) => true, (&Var(ref vL), &Var(ref vR)) => match_vars(vL, vR, &*ctx), - (&Pi(ref xL, ref tL, ref bL), &Pi(ref xR, ref tR, ref bR)) => { + (&Pi(xL, ref tL, ref bL), &Pi(xR, ref tR, ref bR)) => { //ctx <- State.get let eq1 = go(ctx, tL, tR); if eq1 { @@ -164,15 +164,15 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, -> Result, TypeError<'i, S>> where S: Clone + ::std::fmt::Debug + 'i { - match e { - &Const(c) => axiom(c).map(Const), //.map(Cow::Owned), - &Var(V(ref x, n)) => { + match *e { + Const(c) => axiom(c).map(Const), //.map(Cow::Owned), + Var(V(x, n)) => { ctx.lookup(x, n) .cloned() //.map(Cow::Borrowed) - .ok_or_else(|| TypeError::new(ctx, &e, UnboundVariable)) + .ok_or_else(|| TypeError::new(ctx, e, UnboundVariable)) } - &Lam(ref x, ref tA, ref b) => { + Lam(x, ref tA, ref b) => { let ctx2 = ctx.insert(x, (**tA).clone()).map(|e| core::shift(1, V(x, 0), e)); let tB = type_with(&ctx2, b)?; let p = Pi(x, tA.clone(), bx(tB)); @@ -180,7 +180,7 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, //Ok(Cow::Owned(p)) Ok(p) } - &Pi(ref x, ref tA, ref tB) => { + Pi(x, ref tA, ref tB) => { let tA2 = normalize::(&type_with(ctx, tA)?); let kA = match tA2 { Const(k) => k, @@ -199,7 +199,7 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, Ok(k) => Ok(Const(k)), } } - &App(ref f, ref a) => { + App(ref f, ref a) => { let tf = normalize(&type_with(ctx, f)?); let (x, tA, tB) = match tf { Pi(x, tA, tB) => (x, tA, tB), @@ -218,14 +218,14 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, Err(TypeError::new(ctx, e, TypeMismatch((**f).clone(), nf_A, (**a).clone(), nf_A2))) } } - &Let(ref f, ref mt, ref r, ref b) => { + Let(f, ref mt, ref r, ref b) => { let tR = type_with(ctx, r)?; let ttR = normalize::(&type_with(ctx, &tR)?); let kR = match ttR { Const(k) => k, // Don't bother to provide a `let`-specific version of this error // message because this should never happen anyway - _ => return Err(TypeError::new(ctx, &e, InvalidInputType(tR))), + _ => return Err(TypeError::new(ctx, e, InvalidInputType(tR))), }; let ctx2 = ctx.insert(f, tR.clone()); @@ -235,24 +235,24 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, Const(k) => k, // Don't bother to provide a `let`-specific version of this error // message because this should never happen anyway - _ => return Err(TypeError::new(ctx, &e, InvalidOutputType(tB))), + _ => return Err(TypeError::new(ctx, e, InvalidOutputType(tB))), }; if let Err(()) = rule(kR, kB) { - return Err(TypeError::new(ctx, &e, NoDependentLet(tR, tB))); + return Err(TypeError::new(ctx, e, NoDependentLet(tR, tB))); } - if let &Some(ref t) = mt { + if let Some(ref t) = *mt { let nf_t = normalize(t); let nf_tR = normalize(&tR); if !prop_equal(&nf_tR, &nf_t) { - return Err(TypeError::new(ctx, &e, AnnotMismatch((**r).clone(), nf_t, nf_tR))); + return Err(TypeError::new(ctx, e, AnnotMismatch((**r).clone(), nf_t, nf_tR))); } } Ok(tB) } - &Annot(ref x, ref t) => { + Annot(ref x, ref t) => { // This is mainly just to check that `t` is not `Kind` let _ = type_with(ctx, t)?; @@ -265,16 +265,16 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, Err(TypeError::new(ctx, e, AnnotMismatch((**x).clone(), nf_t, nf_t2))) } } - &BuiltinType(t) => Ok(match t { + BuiltinType(t) => Ok(match t { List | Optional => pi("_", Const(Type), Const(Type)), Bool | Natural | Integer | Double | Text => Const(Type), }), - &BoolLit(_) => Ok(BuiltinType(Bool)), - &BoolAnd(ref l, ref r) => op2_type(ctx, e, Bool, CantAnd, l, r), - &BoolOr(ref l, ref r) => op2_type(ctx, e, Bool, CantOr, l, r), - &BoolEQ(ref l, ref r) => op2_type(ctx, e, Bool, CantEQ, l, r), - &BoolNE(ref l, ref r) => op2_type(ctx, e, Bool, CantNE, l, r), - &BoolIf(ref x, ref y, ref z) => { + BoolLit(_) => Ok(BuiltinType(Bool)), + BoolAnd(ref l, ref r) => op2_type(ctx, e, Bool, CantAnd, l, r), + BoolOr(ref l, ref r) => op2_type(ctx, e, Bool, CantOr, l, r), + BoolEQ(ref l, ref r) => op2_type(ctx, e, Bool, CantEQ, l, r), + BoolNE(ref l, ref r) => op2_type(ctx, e, Bool, CantNE, l, r), + BoolIf(ref x, ref y, ref z) => { let tx = normalize(&type_with(ctx, x)?); match tx { BuiltinType(Bool) => {} @@ -299,28 +299,28 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, } Ok(ty) } - &NaturalLit(_) => Ok(BuiltinType(Natural)), - &BuiltinValue(NaturalFold) => + NaturalLit(_) => Ok(BuiltinType(Natural)), + BuiltinValue(NaturalFold) => Ok(pi("_", Natural, pi("natural", Const(Type), pi("succ", pi("_", "natural", "natural"), pi("zero", "natural", "natural"))))), - &BuiltinValue(NaturalBuild) => + BuiltinValue(NaturalBuild) => Ok(pi("_", pi("natural", Const(Type), pi("succ", pi("_", "natural", "natural"), pi("zero", "natural", "natural"))), Natural)), - &BuiltinValue(NaturalIsZero) => Ok(pi("_", Natural, Bool)), - &BuiltinValue(NaturalEven) => Ok(pi("_", Natural, Bool)), - &BuiltinValue(NaturalOdd) => Ok(pi("_", Natural, Bool)), - &NaturalPlus(ref l, ref r) => op2_type(ctx, e, Natural, CantAdd, l, r), - &NaturalTimes(ref l, ref r) => op2_type(ctx, e, Natural, CantMultiply, l, r), - &IntegerLit(_) => Ok(BuiltinType(Integer)), - &DoubleLit(_) => Ok(BuiltinType(Double)), - &TextLit(_) => Ok(BuiltinType(Text)), - &TextAppend(ref l, ref r) => op2_type(ctx, e, Text, CantTextAppend, l, r), - &ListLit(ref t, ref xs) => { + BuiltinValue(NaturalIsZero) | + BuiltinValue(NaturalEven) | + BuiltinValue(NaturalOdd) => Ok(pi("_", Natural, Bool)), + NaturalPlus(ref l, ref r) => op2_type(ctx, e, Natural, CantAdd, l, r), + NaturalTimes(ref l, ref r) => op2_type(ctx, e, Natural, CantMultiply, l, r), + IntegerLit(_) => Ok(BuiltinType(Integer)), + DoubleLit(_) => Ok(BuiltinType(Double)), + TextLit(_) => Ok(BuiltinType(Text)), + TextAppend(ref l, ref r) => op2_type(ctx, e, Text, CantTextAppend, l, r), + ListLit(ref t, ref xs) => { let s = normalize::<_, S, _>(&type_with(ctx, t)?); match s { Const(Type) => {} @@ -336,34 +336,33 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, } Ok(App(bx(BuiltinType(List)), t.clone())) } - &BuiltinValue(ListBuild) => + BuiltinValue(ListBuild) => Ok(pi("a", Const(Type), pi("_", pi("list", Const(Type), pi("cons", pi("_", "a", pi("_", "list", "list")), pi("nil", "list", "list"))), app(List, "a")))), - &BuiltinValue(ListFold) => + BuiltinValue(ListFold) => Ok(pi("a", Const(Type), pi("_", app(List, "a"), pi("list", Const(Type), pi("cons", pi("_", "a", pi("_", "list", "list")), pi("nil", "list", "list")))))), - &BuiltinValue(ListLength) => + BuiltinValue(ListLength) => Ok(pi("a", Const(Type), pi("_", app(List, "a"), Natural))), - &BuiltinValue(ListHead) => + BuiltinValue(ListHead) | + BuiltinValue(ListLast) => Ok(pi("a", Const(Type), pi("_", app(List, "a"), app(Optional, "a")))), - &BuiltinValue(ListLast) => - Ok(pi("a", Const(Type), pi("_", app(List, "a"), app(Optional, "a")))), - &BuiltinValue(ListIndexed) => { + BuiltinValue(ListIndexed) => { let mut m = BTreeMap::new(); m.insert("index", BuiltinType(Natural)); m.insert("value", Expr::from("a")); Ok(pi("a", Const(Type), pi("_", app(List, "a"), app(List, Record(m))))) } - &BuiltinValue(ListReverse) => + BuiltinValue(ListReverse) => Ok(pi("a", Const(Type), pi("_", app(List, "a"), app(List, "a")))), - &OptionalLit(ref t, ref xs) => { + OptionalLit(ref t, ref xs) => { let s = normalize::<_, S, _>(&type_with(ctx, t)?); match s { Const(Type) => {} @@ -383,13 +382,13 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, } Ok(App(bx(BuiltinType(Optional)), t.clone())) } - &BuiltinValue(OptionalFold) => + BuiltinValue(OptionalFold) => Ok(pi("a", Const(Type), pi("_", app(Optional, "a"), pi("optional", Const(Type), pi("just", pi("_", "a", "optional"), pi("nothing", "optional", "optional")))))), - &Record(ref kts) => { + Record(ref kts) => { for (k, t) in kts { let s = normalize::(&type_with(ctx, t)?); match s { @@ -399,7 +398,7 @@ pub fn type_with<'i, S>(ctx: &Context<'i, Expr<'i, S, X>>, } Ok(Const(Type)) } - &RecordLit(ref kvs) => { + RecordLit(ref kvs) => { let kts = kvs.iter().map(|(&k, v)| { let t = type_with(ctx, v)?; let s = normalize::(&type_with(ctx, &t)?); @@ -492,10 +491,10 @@ type_with ctx e@(Merge kvsX kvsY t) = do mapM_ process (Data.Map.toList ktsY) return t */ - &Field(ref r, x) => { + Field(ref r, x) => { let t = normalize(&type_with(ctx, r)?); - match &t { - &Record(ref kts) => + match t { + Record(ref kts) => kts.get(x).cloned().ok_or_else(|| TypeError::new(ctx, e, MissingField(x.to_owned(), t.clone()))), _ => Err(TypeError::new(ctx, e, NotARecord(x.to_owned(), (**r).clone(), t.clone()))), } @@ -506,7 +505,7 @@ type_with ctx (Note s e' ) = case type_with ctx e' of Left (TypeError ctx2 e'' m) -> Left (TypeError ctx2 (Note s e'') m) Right r -> Right r */ - &Embed(p) => match p {}, + Embed(p) => match p {}, _ => panic!("Unimplemented typecheck case: {:?}", e), } } @@ -587,12 +586,12 @@ impl<'i, S: Clone> TypeError<'i, S> { impl<'i, S: fmt::Debug> ::std::error::Error for TypeMessage<'i, S> { fn description(&self) -> &str { - match self { - &UnboundVariable => "Unbound variable", - &InvalidInputType(_) => "Invalid function input", - &InvalidOutputType(_) => "Invalid function output", - &NotAFunction(_, _) => "Not a function", - &TypeMismatch(_, _, _, _) => "Wrong type of function argument", + match *self { + UnboundVariable => "Unbound variable", + InvalidInputType(_) => "Invalid function input", + InvalidOutputType(_) => "Invalid function output", + NotAFunction(_, _) => "Not a function", + TypeMismatch(_, _, _, _) => "Wrong type of function argument", _ => "Unhandled error", } } @@ -600,9 +599,9 @@ impl<'i, S: fmt::Debug> ::std::error::Error for TypeMessage<'i, S> { impl<'i, S> fmt::Display for TypeMessage<'i, S> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match self { - &UnboundVariable => f.write_str(include_str!("errors/UnboundVariable.txt")), - &TypeMismatch(ref e0, ref e1, ref e2, ref e3) => { + match *self { + UnboundVariable => f.write_str(include_str!("errors/UnboundVariable.txt")), + TypeMismatch(ref e0, ref e1, ref e2, ref e3) => { let template = include_str!("errors/TypeMismatch.txt"); let s = template .replace("$txt0", &format!("{}", e0)) -- cgit v1.2.3