Skip to content

Commit 2ea52a3

Browse files
committed
refinement to technique used to not run regionck
1 parent e235f6c commit 2ea52a3

File tree

12 files changed

+66
-89
lines changed

12 files changed

+66
-89
lines changed

src/libcore/cleanup.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use ptr::mut_null;
1515
use repr::BoxRepr;
1616
use sys::TypeDesc;
1717
use cast::transmute;
18-
use unstable::lang::clear_task_borrow_list;
18+
#[cfg(notest)] use unstable::lang::clear_task_borrow_list;
1919

2020
#[cfg(notest)] use ptr::to_unsafe_ptr;
2121

src/librustc/driver/session.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ pub impl Session_ {
188188
fn err(@self, msg: &str) {
189189
self.span_diagnostic.handler().err(msg)
190190
}
191+
fn err_count(@self) -> uint {
192+
self.span_diagnostic.handler().err_count()
193+
}
191194
fn has_errors(@self) -> bool {
192195
self.span_diagnostic.handler().has_errors()
193196
}

src/librustc/middle/typeck/check/mod.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,11 @@ pub impl PurityState {
207207
}
208208

209209
pub struct FnCtxt {
210-
// var_bindings, locals and next_var_id are shared
211-
// with any nested functions that capture the environment
212-
// (and with any functions whose environment is being captured).
210+
// Number of errors that had been reported when we started
211+
// checking this function. On exit, if we find that *more* errors
212+
// have been reported, we will skip regionck and other work that
213+
// expects the types within the function to be consistent.
214+
err_count_on_creation: uint,
213215

214216
ret_ty: ty::t,
215217
// Used by loop bodies that return from the outer function
@@ -263,6 +265,7 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt,
263265
// It's kind of a kludge to manufacture a fake function context
264266
// and statement context, but we might as well do write the code only once
265267
@mut FnCtxt {
268+
err_count_on_creation: ccx.tcx.sess.err_count(),
266269
ret_ty: rty,
267270
indirect_ret_ty: None,
268271
ps: PurityState::function(ast::pure_fn, 0),
@@ -328,6 +331,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
328331
*/
329332

330333
let tcx = ccx.tcx;
334+
let err_count_on_creation = tcx.sess.err_count();
331335

332336
// ______________________________________________________________________
333337
// First, we have to replace any bound regions in the fn and self
@@ -368,6 +372,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
368372
};
369373

370374
@mut FnCtxt {
375+
err_count_on_creation: err_count_on_creation,
371376
ret_ty: ret_ty,
372377
indirect_ret_ty: indirect_ret_ty,
373378
ps: PurityState::function(purity, id),
@@ -642,7 +647,12 @@ impl AstConv for FnCtxt {
642647
}
643648

644649
pub impl FnCtxt {
645-
fn infcx(&self) -> @mut infer::InferCtxt { self.inh.infcx }
650+
fn infcx(&self) -> @mut infer::InferCtxt {
651+
self.inh.infcx
652+
}
653+
fn err_count_since_creation(&self) -> uint {
654+
self.ccx.tcx.sess.err_count() - self.err_count_on_creation
655+
}
646656
fn search_in_scope_regions(
647657
&self,
648658
span: span,

src/librustc/middle/typeck/check/regionck.rs

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ pub impl Rcx {
138138

139139
pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::expr) {
140140
let rcx = @mut Rcx { fcx: fcx, errors_reported: 0 };
141-
if !fcx.tcx().sess.has_errors() { // regionck assumes typeck succeeded
141+
if fcx.err_count_since_creation() == 0 {
142+
// regionck assumes typeck succeeded
142143
let v = regionck_visitor();
143144
(v.visit_expr)(e, rcx, v);
144145
}
@@ -147,7 +148,8 @@ pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::expr) {
147148

148149
pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::blk) {
149150
let rcx = @mut Rcx { fcx: fcx, errors_reported: 0 };
150-
if !fcx.tcx().sess.has_errors() { // regionck assumes typeck succeeded
151+
if fcx.err_count_since_creation() == 0 {
152+
// regionck assumes typeck succeeded
151153
let v = regionck_visitor();
152154
(v.visit_block)(blk, rcx, v);
153155
}
@@ -409,10 +411,6 @@ fn constrain_callee(rcx: @mut Rcx,
409411
let call_region = ty::re_scope(call_expr.id);
410412

411413
let callee_ty = rcx.resolve_node_type(call_expr.callee_id);
412-
if ty::type_is_error(callee_ty) {
413-
return;
414-
}
415-
416414
match ty::get(callee_ty).sty {
417415
ty::ty_bare_fn(*) => { }
418416
ty::ty_closure(ref closure_ty) => {
@@ -432,9 +430,12 @@ fn constrain_callee(rcx: @mut Rcx,
432430
}
433431
}
434432
_ => {
435-
tcx.sess.span_bug(
436-
callee_expr.span,
437-
fmt!("Calling non-function: %s", callee_ty.repr(tcx)));
433+
// this should not happen, but it does if the program is
434+
// erroneous
435+
//
436+
// tcx.sess.span_bug(
437+
// callee_expr.span,
438+
// fmt!("Calling non-function: %s", callee_ty.repr(tcx)));
438439
}
439440
}
440441
}
@@ -456,9 +457,6 @@ fn constrain_call(rcx: @mut Rcx,
456457
debug!("constrain_call(call_expr=%s, implicitly_ref_args=%?)",
457458
call_expr.repr(tcx), implicitly_ref_args);
458459
let callee_ty = rcx.resolve_node_type(call_expr.callee_id);
459-
if ty::type_is_error(callee_ty) {
460-
return;
461-
}
462460
let fn_sig = ty::ty_fn_sig(callee_ty);
463461

464462
// `callee_region` is the scope representing the time in which the
@@ -919,7 +917,7 @@ pub mod guarantor {
919917
// expressions, both of which always yield a region variable, so
920918
// mk_subr should never fail.
921919
let rptr_ty = rcx.resolve_node_type(id);
922-
if !ty::type_is_error(rptr_ty) && !ty::type_is_bot(rptr_ty) {
920+
if !ty::type_is_bot(rptr_ty) {
923921
let tcx = rcx.fcx.ccx.tcx;
924922
debug!("rptr_ty=%s", ty_to_str(tcx, rptr_ty));
925923
let r = ty::ty_region(tcx, span, rptr_ty);
@@ -1216,29 +1214,25 @@ pub mod guarantor {
12161214
}
12171215
ast::pat_region(p) => {
12181216
let rptr_ty = rcx.resolve_node_type(pat.id);
1219-
if !ty::type_is_error(rptr_ty) {
1220-
let r = ty::ty_region(rcx.fcx.tcx(), pat.span, rptr_ty);
1221-
link_ref_bindings_in_pat(rcx, p, Some(r));
1222-
}
1217+
let r = ty::ty_region(rcx.fcx.tcx(), pat.span, rptr_ty);
1218+
link_ref_bindings_in_pat(rcx, p, Some(r));
12231219
}
12241220
ast::pat_lit(*) => {}
12251221
ast::pat_range(*) => {}
12261222
ast::pat_vec(ref before, ref slice, ref after) => {
12271223
let vec_ty = rcx.resolve_node_type(pat.id);
1228-
if !ty::type_is_error(vec_ty) {
1229-
let vstore = ty::ty_vstore(vec_ty);
1230-
let guarantor1 = match vstore {
1231-
ty::vstore_fixed(_) | ty::vstore_uniq => guarantor,
1232-
ty::vstore_slice(r) => Some(r),
1233-
ty::vstore_box => None
1234-
};
1235-
1236-
link_ref_bindings_in_pats(rcx, before, guarantor1);
1237-
for slice.each |&p| {
1238-
link_ref_bindings_in_pat(rcx, p, guarantor);
1239-
}
1240-
link_ref_bindings_in_pats(rcx, after, guarantor1);
1224+
let vstore = ty::ty_vstore(vec_ty);
1225+
let guarantor1 = match vstore {
1226+
ty::vstore_fixed(_) | ty::vstore_uniq => guarantor,
1227+
ty::vstore_slice(r) => Some(r),
1228+
ty::vstore_box => None
1229+
};
1230+
1231+
link_ref_bindings_in_pats(rcx, before, guarantor1);
1232+
for slice.each |&p| {
1233+
link_ref_bindings_in_pat(rcx, p, guarantor);
12411234
}
1235+
link_ref_bindings_in_pats(rcx, after, guarantor1);
12421236
}
12431237
}
12441238
}

src/librustc/middle/typeck/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,11 @@ pub fn check_crate(tcx: ty::ctxt,
414414
time(time_passes, ~"type collecting", ||
415415
collect::collect_item_types(ccx, crate));
416416

417-
time(time_passes, ~"method resolution", ||
417+
// this ensures that later parts of type checking can assume that items
418+
// have valid types and not error
419+
tcx.sess.abort_if_errors();
420+
421+
time(time_passes, ~"coherence checking", ||
418422
coherence::check_coherence(ccx, crate));
419423

420424
time(time_passes, ~"type checking", ||

src/libsyntax/diagnostic.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub trait handler {
2424
fn fatal(@mut self, msg: &str) -> !;
2525
fn err(@mut self, msg: &str);
2626
fn bump_err_count(@mut self);
27+
fn err_count(@mut self) -> uint;
2728
fn has_errors(@mut self) -> bool;
2829
fn abort_if_errors(@mut self);
2930
fn warn(@mut self, msg: &str);
@@ -98,7 +99,12 @@ impl handler for HandlerT {
9899
fn bump_err_count(@mut self) {
99100
self.err_count += 1u;
100101
}
101-
fn has_errors(@mut self) -> bool { self.err_count > 0u }
102+
fn err_count(@mut self) -> uint {
103+
self.err_count
104+
}
105+
fn has_errors(@mut self) -> bool {
106+
self.err_count > 0u
107+
}
102108
fn abort_if_errors(@mut self) {
103109
let s;
104110
match self.err_count {

src/test/compile-fail/dead-code-ret.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
// except according to those terms.
1111

1212

13-
// error-pattern: dead
13+
fn f(caller: &str) {
14+
debug!(caller);
15+
let x: uint = 0u32; // induce type error //~ ERROR mismatched types
16+
}
1417

15-
fn f(caller: str) { debug!(caller); }
16-
17-
fn main() { return f("main"); debug!("Paul is dead"); }
18+
fn main() {
19+
return f("main");
20+
debug!("Paul is dead"); //~ WARNING unreachable
21+
}

src/test/compile-fail/for-loop-decl.rs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/test/compile-fail/regions-bounds.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> {
2323
return e; //~ ERROR mismatched types: expected `a_class/&'b ` but found `a_class/&'a `
2424
}
2525

26-
fn a_fn4<'a,'b>(e: int<'a>) -> int<'b> {
27-
//~^ ERROR region parameters are not allowed on this type
28-
//~^^ ERROR region parameters are not allowed on this type
29-
return e;
26+
fn a_fn4<'a,'b>() {
27+
let _: int<'a> = 1; //~ ERROR region parameters are not allowed on this type
3028
}
3129

3230
fn main() { }

src/test/compile-fail/regions-ret-borrowed-1.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ fn with<'a, R>(f: &fn(x: &'a int) -> R) -> R {
1818

1919
fn return_it<'a>() -> &'a int {
2020
with(|o| o) //~ ERROR mismatched types
21-
//~^ ERROR reference is not valid outside of its lifetime
22-
//~^^ ERROR reference is not valid outside of its lifetime
2321
}
2422

2523
fn main() {

src/test/compile-fail/regions-ret-borrowed.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ fn with<R>(f: &fn(x: &int) -> R) -> R {
2121

2222
fn return_it() -> &int {
2323
with(|o| o) //~ ERROR mismatched types
24-
//~^ ERROR reference is not valid outside of its lifetime
25-
//~^^ ERROR reference is not valid outside of its lifetime
2624
}
2725

2826
fn main() {

src/test/compile-fail/type-shadow.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@
99
// option. This file may not be copied, modified, or distributed
1010
// except according to those terms.
1111

12-
13-
// error-pattern: mismatched types
14-
1512
fn main() {
1613
type X = int;
1714
type Y = X;
1815
if true {
19-
type X = str;
20-
let y: Y = "hello";
16+
type X = &'static str;
17+
let y: Y = "hello"; //~ ERROR mismatched types
2118
}
2219
}

0 commit comments

Comments
 (0)