auto merge of #13330 : huonw/rust/loop-error, r=alexcrichton

rustc: move the check_loop pass earlier.

This pass is purely AST based, and by running it earlier we emit more
useful error messages, e.g. type inference fails in the case of 
`let r = break;` with few constraints on `r`, but it's more useful to be told that
the `break` is outside the loop (rather than a type error) when it is.

Closes #13292.
This commit is contained in:
bors 2014-04-05 04:41:33 -07:00
commit e7148592ad
3 changed files with 11 additions and 11 deletions

View File

@ -323,6 +323,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
let region_map = time(time_passes, "region resolution", (), |_| let region_map = time(time_passes, "region resolution", (), |_|
middle::region::resolve_crate(&sess, krate)); middle::region::resolve_crate(&sess, krate));
time(time_passes, "loop checking", (), |_|
middle::check_loop::check_crate(&sess, krate));
let ty_cx = ty::mk_ctxt(sess, def_map, named_region_map, ast_map, let ty_cx = ty::mk_ctxt(sess, def_map, named_region_map, ast_map,
freevars, region_map, lang_items); freevars, region_map, lang_items);
@ -348,9 +351,6 @@ pub fn phase_3_run_analysis_passes(sess: Session,
time(time_passes, "effect checking", (), |_| time(time_passes, "effect checking", (), |_|
middle::effect::check_crate(&ty_cx, method_map, krate)); middle::effect::check_crate(&ty_cx, method_map, krate));
time(time_passes, "loop checking", (), |_|
middle::check_loop::check_crate(&ty_cx, krate));
let middle::moves::MoveMaps {moves_map, moved_variables_set, let middle::moves::MoveMaps {moves_map, moved_variables_set,
capture_map} = capture_map} =
time(time_passes, "compute moves", (), |_| time(time_passes, "compute moves", (), |_|

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::ty; use driver::session::Session;
use syntax::ast; use syntax::ast;
use syntax::codemap::Span; use syntax::codemap::Span;
@ -21,11 +21,11 @@ enum Context {
} }
struct CheckLoopVisitor<'a> { struct CheckLoopVisitor<'a> {
tcx: &'a ty::ctxt, sess: &'a Session,
} }
pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) { pub fn check_crate(sess: &Session, krate: &ast::Crate) {
visit::walk_crate(&mut CheckLoopVisitor { tcx: tcx }, krate, Normal) visit::walk_crate(&mut CheckLoopVisitor { sess: sess }, krate, Normal)
} }
impl<'a> Visitor<Context> for CheckLoopVisitor<'a> { impl<'a> Visitor<Context> for CheckLoopVisitor<'a> {
@ -57,12 +57,10 @@ impl<'a> CheckLoopVisitor<'a> {
match cx { match cx {
Loop => {} Loop => {}
Closure => { Closure => {
self.tcx.sess.span_err(span, format!("`{}` inside of a closure", self.sess.span_err(span, format!("`{}` inside of a closure", name));
name));
} }
Normal => { Normal => {
self.tcx.sess.span_err(span, format!("`{}` outside of loop", self.sess.span_err(span, format!("`{}` outside of loop", name));
name));
} }
} }
} }

View File

@ -30,4 +30,6 @@ fn main() {
} }
let rs: Foo = Foo{t: pth}; let rs: Foo = Foo{t: pth};
let unconstrained = break; //~ ERROR: `break` outside of loop
} }