Make typechecker compositional

The typechecker previously passed around a boolean return flag to
indicate whether it saw something with type _|_ (that is, something
it knows at compile-time will definitely diverge) and also had some
manual checks for the `ty_err` pseudo-type that represents a previous
type error. This was because the typing rules implemented by the
typechecker didn't properly propagate _|_ and ty_err. I fixed it.

This also required changing expected error messages in a few tests,
as now we're printing out fewer derived errors -- in fact, at this
point we should print out no derived errors, so report any that
you see (ones that include "[type error]") as bugs.
This commit is contained in:
Tim Chevalier 2013-03-20 12:55:18 -07:00
parent 63a292fd86
commit db00362313
13 changed files with 819 additions and 500 deletions

View file

@ -25,4 +25,11 @@ pub enum e {
pub fn nominal() -> e { e_val }
pub pure fn nominal_eq(e1: e, e2: e) -> bool { true }
impl Eq for e {
pure fn eq(&self, other: &e) -> bool { nominal_eq(*self, *other) }
pure fn ne(&self, other: &e) -> bool { !nominal_eq(*self, *other) }
}
pub fn f() -> int { 10 }

View file

@ -22,6 +22,13 @@ pub enum e {
e_val
}
impl Eq for e {
pure fn eq(&self, other: &e) -> bool { !nominal_neq(*self, *other) }
pure fn ne(&self, other: &e) -> bool { nominal_neq(*self, *other) }
}
pub fn nominal() -> e { e_val }
pub pure fn nominal_neq(e1: e, e2: e) -> bool { false }
pub fn f() -> int { 20 }

View file

@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern: mismatched types
struct clam {
x: @int,
y: @int,
@ -21,12 +20,12 @@ struct fish {
fn main() {
let a: clam = clam{x: @1, y: @2};
let b: clam = clam{x: @10, y: @20};
let z: int = a.x + b.y;
let z: int = a.x + b.y; //~ ERROR binary operation + cannot be applied to type `@int`
debug!(z);
fail_unless!((z == 21));
let forty: fish = fish{a: @40};
let two: fish = fish{a: @2};
let answer: int = forty.a + two.a;
let answer: int = forty.a + two.a; //~ ERROR binary operation + cannot be applied to type `@int`
debug!(answer);
fail_unless!((answer == 42));
}

View file

@ -11,12 +11,12 @@
// xfail-fast
// aux-build:crateresolve5-1.rs
// aux-build:crateresolve5-2.rs
// error-pattern:mismatched types
extern mod cr5_1 (name = "crateresolve5", vers = "0.1");
extern mod cr5_2 (name = "crateresolve5", vers = "0.2");
fn main() {
// Nominal types from two multiple versions of a crate are different types
fail_unless!(cr5_1::nominal() == cr5_2::nominal());
fail_unless!(cr5_1::nominal() == cr5_2::nominal()); //~ ERROR mismatched types: expected
}

View file

@ -0,0 +1,15 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct NonCopyable(());
fn main() {
let z = NonCopyable{ p: () }; //~ ERROR structure has no field named `p`
}

View file

@ -12,10 +12,9 @@
extern mod std;
// error-pattern: mismatched types
enum bar { t1((), Option<~[int]>), t2, }
fn foo(t: bar) -> int { match t { t1(_, Some(x)) => { return x * 3; } _ => { fail!(); } } }
// n.b. my change changes this error message, but I think it's right -- tjc
fn foo(t: bar) -> int { match t { t1(_, Some(x)) => { return x * 3; } _ => { fail!(); } } } //~ ERROR binary operation * cannot be applied to
fn main() { }