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:
parent
63a292fd86
commit
db00362313
13 changed files with 819 additions and 500 deletions
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
15
src/test/compile-fail/issue-4736.rs
Normal file
15
src/test/compile-fail/issue-4736.rs
Normal 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`
|
||||
}
|
||||
|
|
@ -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() { }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue