about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-05-06 09:00:37 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-05-06 09:00:37 -0400
commit2ea52a38e59b85b4b6998661b38425ce29839aed (patch)
treeade9272b7890755aa014a4f52b46c382e65be776 /src
parente235f6ca53bac14158a6320aab49f31bd8e8bbe0 (diff)
downloadrust-2ea52a38e59b85b4b6998661b38425ce29839aed.tar.gz
rust-2ea52a38e59b85b4b6998661b38425ce29839aed.zip
refinement to technique used to not run regionck
Diffstat (limited to 'src')
-rw-r--r--src/libcore/cleanup.rs2
-rw-r--r--src/librustc/driver/session.rs3
-rw-r--r--src/librustc/middle/typeck/check/mod.rs18
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs54
-rw-r--r--src/librustc/middle/typeck/mod.rs6
-rw-r--r--src/libsyntax/diagnostic.rs8
-rw-r--r--src/test/compile-fail/dead-code-ret.rs12
-rw-r--r--src/test/compile-fail/for-loop-decl.rs35
-rw-r--r--src/test/compile-fail/regions-bounds.rs6
-rw-r--r--src/test/compile-fail/regions-ret-borrowed-1.rs2
-rw-r--r--src/test/compile-fail/regions-ret-borrowed.rs2
-rw-r--r--src/test/compile-fail/type-shadow.rs7
12 files changed, 66 insertions, 89 deletions
diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs
index 435b1cb7f34..06f6185586d 100644
--- a/src/libcore/cleanup.rs
+++ b/src/libcore/cleanup.rs
@@ -15,7 +15,7 @@ use ptr::mut_null;
 use repr::BoxRepr;
 use sys::TypeDesc;
 use cast::transmute;
-use unstable::lang::clear_task_borrow_list;
+#[cfg(notest)] use unstable::lang::clear_task_borrow_list;
 
 #[cfg(notest)] use ptr::to_unsafe_ptr;
 
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 3b9bbbb9f1c..582e1d606bc 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -188,6 +188,9 @@ pub impl Session_ {
     fn err(@self, msg: &str) {
         self.span_diagnostic.handler().err(msg)
     }
+    fn err_count(@self) -> uint {
+        self.span_diagnostic.handler().err_count()
+    }
     fn has_errors(@self) -> bool {
         self.span_diagnostic.handler().has_errors()
     }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 5357d092a90..7e63db89edb 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -207,9 +207,11 @@ pub impl PurityState {
 }
 
 pub struct FnCtxt {
-    // var_bindings, locals and next_var_id are shared
-    // with any nested functions that capture the environment
-    // (and with any functions whose environment is being captured).
+    // Number of errors that had been reported when we started
+    // checking this function. On exit, if we find that *more* errors
+    // have been reported, we will skip regionck and other work that
+    // expects the types within the function to be consistent.
+    err_count_on_creation: uint,
 
     ret_ty: ty::t,
     // Used by loop bodies that return from the outer function
@@ -263,6 +265,7 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt,
 // It's kind of a kludge to manufacture a fake function context
 // and statement context, but we might as well do write the code only once
     @mut FnCtxt {
+        err_count_on_creation: ccx.tcx.sess.err_count(),
         ret_ty: rty,
         indirect_ret_ty: None,
         ps: PurityState::function(ast::pure_fn, 0),
@@ -328,6 +331,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
      */
 
     let tcx = ccx.tcx;
+    let err_count_on_creation = tcx.sess.err_count();
 
     // ______________________________________________________________________
     // First, we have to replace any bound regions in the fn and self
@@ -368,6 +372,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
         };
 
         @mut FnCtxt {
+            err_count_on_creation: err_count_on_creation,
             ret_ty: ret_ty,
             indirect_ret_ty: indirect_ret_ty,
             ps: PurityState::function(purity, id),
@@ -642,7 +647,12 @@ impl AstConv for FnCtxt {
 }
 
 pub impl FnCtxt {
-    fn infcx(&self) -> @mut infer::InferCtxt { self.inh.infcx }
+    fn infcx(&self) -> @mut infer::InferCtxt {
+        self.inh.infcx
+    }
+    fn err_count_since_creation(&self) -> uint {
+        self.ccx.tcx.sess.err_count() - self.err_count_on_creation
+    }
     fn search_in_scope_regions(
         &self,
         span: span,
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index b4a1cab7b21..03dd32353db 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -138,7 +138,8 @@ pub impl Rcx {
 
 pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::expr) {
     let rcx = @mut Rcx { fcx: fcx, errors_reported: 0 };
-    if !fcx.tcx().sess.has_errors() { // regionck assumes typeck succeeded
+    if fcx.err_count_since_creation() == 0 {
+        // regionck assumes typeck succeeded
         let v = regionck_visitor();
         (v.visit_expr)(e, rcx, v);
     }
@@ -147,7 +148,8 @@ pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::expr) {
 
 pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::blk) {
     let rcx = @mut Rcx { fcx: fcx, errors_reported: 0 };
-    if !fcx.tcx().sess.has_errors() { // regionck assumes typeck succeeded
+    if fcx.err_count_since_creation() == 0 {
+        // regionck assumes typeck succeeded
         let v = regionck_visitor();
         (v.visit_block)(blk, rcx, v);
     }
@@ -409,10 +411,6 @@ fn constrain_callee(rcx: @mut Rcx,
     let call_region = ty::re_scope(call_expr.id);
 
     let callee_ty = rcx.resolve_node_type(call_expr.callee_id);
-    if ty::type_is_error(callee_ty) {
-        return;
-    }
-
     match ty::get(callee_ty).sty {
         ty::ty_bare_fn(*) => { }
         ty::ty_closure(ref closure_ty) => {
@@ -432,9 +430,12 @@ fn constrain_callee(rcx: @mut Rcx,
             }
         }
         _ => {
-            tcx.sess.span_bug(
-                callee_expr.span,
-                fmt!("Calling non-function: %s", callee_ty.repr(tcx)));
+            // this should not happen, but it does if the program is
+            // erroneous
+            //
+            // tcx.sess.span_bug(
+            //     callee_expr.span,
+            //     fmt!("Calling non-function: %s", callee_ty.repr(tcx)));
         }
     }
 }
@@ -456,9 +457,6 @@ fn constrain_call(rcx: @mut Rcx,
     debug!("constrain_call(call_expr=%s, implicitly_ref_args=%?)",
            call_expr.repr(tcx), implicitly_ref_args);
     let callee_ty = rcx.resolve_node_type(call_expr.callee_id);
-    if ty::type_is_error(callee_ty) {
-        return;
-    }
     let fn_sig = ty::ty_fn_sig(callee_ty);
 
     // `callee_region` is the scope representing the time in which the
@@ -919,7 +917,7 @@ pub mod guarantor {
         // expressions, both of which always yield a region variable, so
         // mk_subr should never fail.
         let rptr_ty = rcx.resolve_node_type(id);
-        if !ty::type_is_error(rptr_ty) && !ty::type_is_bot(rptr_ty) {
+        if !ty::type_is_bot(rptr_ty) {
             let tcx = rcx.fcx.ccx.tcx;
             debug!("rptr_ty=%s", ty_to_str(tcx, rptr_ty));
             let r = ty::ty_region(tcx, span, rptr_ty);
@@ -1216,29 +1214,25 @@ pub mod guarantor {
             }
             ast::pat_region(p) => {
                 let rptr_ty = rcx.resolve_node_type(pat.id);
-                if !ty::type_is_error(rptr_ty) {
-                    let r = ty::ty_region(rcx.fcx.tcx(), pat.span, rptr_ty);
-                    link_ref_bindings_in_pat(rcx, p, Some(r));
-                }
+                let r = ty::ty_region(rcx.fcx.tcx(), pat.span, rptr_ty);
+                link_ref_bindings_in_pat(rcx, p, Some(r));
             }
             ast::pat_lit(*) => {}
             ast::pat_range(*) => {}
             ast::pat_vec(ref before, ref slice, ref after) => {
                 let vec_ty = rcx.resolve_node_type(pat.id);
-                if !ty::type_is_error(vec_ty) {
-                    let vstore = ty::ty_vstore(vec_ty);
-                    let guarantor1 = match vstore {
-                        ty::vstore_fixed(_) | ty::vstore_uniq => guarantor,
-                        ty::vstore_slice(r) => Some(r),
-                        ty::vstore_box => None
-                    };
-
-                    link_ref_bindings_in_pats(rcx, before, guarantor1);
-                    for slice.each |&p| {
-                        link_ref_bindings_in_pat(rcx, p, guarantor);
-                    }
-                    link_ref_bindings_in_pats(rcx, after, guarantor1);
+                let vstore = ty::ty_vstore(vec_ty);
+                let guarantor1 = match vstore {
+                    ty::vstore_fixed(_) | ty::vstore_uniq => guarantor,
+                    ty::vstore_slice(r) => Some(r),
+                    ty::vstore_box => None
+                };
+
+                link_ref_bindings_in_pats(rcx, before, guarantor1);
+                for slice.each |&p| {
+                    link_ref_bindings_in_pat(rcx, p, guarantor);
                 }
+                link_ref_bindings_in_pats(rcx, after, guarantor1);
             }
         }
     }
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 0012eb70030..1a152f3c291 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -414,7 +414,11 @@ pub fn check_crate(tcx: ty::ctxt,
     time(time_passes, ~"type collecting", ||
         collect::collect_item_types(ccx, crate));
 
-    time(time_passes, ~"method resolution", ||
+    // this ensures that later parts of type checking can assume that items
+    // have valid types and not error
+    tcx.sess.abort_if_errors();
+
+    time(time_passes, ~"coherence checking", ||
         coherence::check_coherence(ccx, crate));
 
     time(time_passes, ~"type checking", ||
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 0f2374a892b..b313a2fc6fc 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -24,6 +24,7 @@ pub trait handler {
     fn fatal(@mut self, msg: &str) -> !;
     fn err(@mut self, msg: &str);
     fn bump_err_count(@mut self);
+    fn err_count(@mut self) -> uint;
     fn has_errors(@mut self) -> bool;
     fn abort_if_errors(@mut self);
     fn warn(@mut self, msg: &str);
@@ -98,7 +99,12 @@ impl handler for HandlerT {
     fn bump_err_count(@mut self) {
         self.err_count += 1u;
     }
-    fn has_errors(@mut self) -> bool { self.err_count > 0u }
+    fn err_count(@mut self) -> uint {
+        self.err_count
+    }
+    fn has_errors(@mut self) -> bool {
+        self.err_count > 0u
+    }
     fn abort_if_errors(@mut self) {
         let s;
         match self.err_count {
diff --git a/src/test/compile-fail/dead-code-ret.rs b/src/test/compile-fail/dead-code-ret.rs
index 97f6149b162..5fa796db884 100644
--- a/src/test/compile-fail/dead-code-ret.rs
+++ b/src/test/compile-fail/dead-code-ret.rs
@@ -10,8 +10,12 @@
 // except according to those terms.
 
 
-// error-pattern: dead
+fn f(caller: &str) {
+    debug!(caller);
+    let x: uint = 0u32; // induce type error //~ ERROR mismatched types
+}
 
-fn f(caller: str) { debug!(caller); }
-
-fn main() { return f("main"); debug!("Paul is dead"); }
+fn main() {
+    return f("main");
+    debug!("Paul is dead"); //~ WARNING unreachable
+}
diff --git a/src/test/compile-fail/for-loop-decl.rs b/src/test/compile-fail/for-loop-decl.rs
deleted file mode 100644
index de28d726777..00000000000
--- a/src/test/compile-fail/for-loop-decl.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2012 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.
-
-// error-pattern: mismatched types
-extern mod std;
-use std::bitv;
-use core::hashmap::HashMap;
-
-struct FnInfo {
-    vars: HashMap<uint, VarInfo>
-}
-
-struct VarInfo {
-    a: uint,
-    b: uint,
-}
-
-fn bitv_to_str(enclosing: FnInfo, v: ~bitv::Bitv) -> str {
-    let s = "";
-
-    // error is that the value type in the hash map is var_info, not a box
-    for enclosing.vars.each_value |val| {
-        if *v.get(val) { s += "foo"; }
-    }
-    return s;
-}
-
-fn main() { debug!("OK"); }
diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs
index cccd135e9f8..ab2620d46fd 100644
--- a/src/test/compile-fail/regions-bounds.rs
+++ b/src/test/compile-fail/regions-bounds.rs
@@ -23,10 +23,8 @@ fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> {
     return e; //~ ERROR mismatched types: expected `a_class/&'b ` but found `a_class/&'a `
 }
 
-fn a_fn4<'a,'b>(e: int<'a>) -> int<'b> {
-    //~^ ERROR region parameters are not allowed on this type
-    //~^^ ERROR region parameters are not allowed on this type
-    return e;
+fn a_fn4<'a,'b>() {
+    let _: int<'a> = 1; //~ ERROR region parameters are not allowed on this type
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/regions-ret-borrowed-1.rs b/src/test/compile-fail/regions-ret-borrowed-1.rs
index f600f6f6edd..a572d90313b 100644
--- a/src/test/compile-fail/regions-ret-borrowed-1.rs
+++ b/src/test/compile-fail/regions-ret-borrowed-1.rs
@@ -18,8 +18,6 @@ fn with<'a, R>(f: &fn(x: &'a int) -> R) -> R {
 
 fn return_it<'a>() -> &'a int {
     with(|o| o) //~ ERROR mismatched types
-        //~^ ERROR reference is not valid outside of its lifetime
-        //~^^ ERROR reference is not valid outside of its lifetime
 }
 
 fn main() {
diff --git a/src/test/compile-fail/regions-ret-borrowed.rs b/src/test/compile-fail/regions-ret-borrowed.rs
index a3540f8f931..ec9a908ba98 100644
--- a/src/test/compile-fail/regions-ret-borrowed.rs
+++ b/src/test/compile-fail/regions-ret-borrowed.rs
@@ -21,8 +21,6 @@ fn with<R>(f: &fn(x: &int) -> R) -> R {
 
 fn return_it() -> &int {
     with(|o| o) //~ ERROR mismatched types
-        //~^ ERROR reference is not valid outside of its lifetime
-        //~^^ ERROR reference is not valid outside of its lifetime
 }
 
 fn main() {
diff --git a/src/test/compile-fail/type-shadow.rs b/src/test/compile-fail/type-shadow.rs
index a9b4a85e638..c4a412f64c8 100644
--- a/src/test/compile-fail/type-shadow.rs
+++ b/src/test/compile-fail/type-shadow.rs
@@ -9,14 +9,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-// error-pattern: mismatched types
-
 fn main() {
     type X = int;
     type Y = X;
     if true {
-        type X = str;
-        let y: Y = "hello";
+        type X = &'static str;
+        let y: Y = "hello"; //~ ERROR mismatched types
     }
 }