From 0cc5e6c83f9d0f64ecd69cdca06511527f4f1554 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 11 Nov 2013 11:16:42 -0800 Subject: [PATCH 1/2] Remove resolve's xray infrastructure Since the removal of privacy from resolve, this flag is no longer necessary to get the test runner working. All of the privacy checks are bypassed by a special item attribute in the privacy visitor. Closes #4947 --- src/librustc/middle/resolve.rs | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 23fef5e351674..4861fa19f7e8f 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -25,7 +25,6 @@ use syntax::ast::*; use syntax::ast; use syntax::ast_util::{def_id_of_def, local_def, mtwt_resolve}; use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; -use syntax::attr; use syntax::parse::token; use syntax::parse::token::{ident_interner, interner_get}; use syntax::parse::token::special_idents; @@ -254,19 +253,6 @@ enum MethodSort { Provided(NodeId) } -// The X-ray flag indicates that a context has the X-ray privilege, which -// allows it to reference private names. Currently, this is used for the test -// runner. -// -// FIXME #4947: The X-ray flag is kind of questionable in the first -// place. It might be better to introduce an expr_xray_path instead. - -#[deriving(Eq)] -enum XrayFlag { - NoXray, //< Private items cannot be accessed. - Xray //< Private items can be accessed. -} - enum UseLexicalScopeFlag { DontUseLexicalScope, UseLexicalScope @@ -831,7 +817,6 @@ fn Resolver(session: Session, type_ribs: @mut ~[], label_ribs: @mut ~[], - xray_context: NoXray, current_trait_refs: None, self_ident: special_idents::self_, @@ -883,10 +868,6 @@ struct Resolver { // The current set of local scopes, for labels. label_ribs: @mut ~[@Rib], - // Whether the current context is an X-ray context. An X-ray context is - // allowed to access private names of any module. - xray_context: XrayFlag, - // The trait that the current context can refer to. current_trait_refs: Option<~[DefId]>, @@ -3545,13 +3526,6 @@ impl Resolver { debug!("(resolving item) resolving {}", self.session.str_of(item.ident)); - // Items with the !resolve_unexported attribute are X-ray contexts. - // This is used to allow the test runner to run unexported tests. - let orig_xray_flag = self.xray_context; - if attr::contains_name(item.attrs, "!resolve_unexported") { - self.xray_context = Xray; - } - match item.node { // enum item: resolve all the variants' discrs, @@ -3715,8 +3689,6 @@ impl Resolver { fail!("item macros unimplemented") } } - - self.xray_context = orig_xray_flag; } fn with_type_parameter_rib(&mut self, From 5fdbcc4020a440e18a3c570ffad5d2bb089c08db Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 11 Nov 2013 11:29:15 -0800 Subject: [PATCH 2/2] Improve error message for breaks in blocks Before it was always stated that it was a "break outside of a loop" when you could very well be in a loop, but just in a block instead. Closes #3064 --- src/librustc/middle/check_loop.rs | 86 +++++++++---------- src/test/compile-fail/break-outside-loop.rs | 19 +++- .../compile-fail/return-in-block-function.rs | 2 +- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index a6aab151e5ad9..8a320f88649a0 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -8,68 +8,68 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use middle::ty; -use syntax::ast::*; -use syntax::visit; +use syntax::ast; +use syntax::codemap::Span; use syntax::visit::Visitor; +use syntax::visit; -#[deriving(Clone)] -pub struct Context { - in_loop: bool, - can_ret: bool +#[deriving(Clone, Eq)] +enum Context { + Normal, Loop, Closure } struct CheckLoopVisitor { tcx: ty::ctxt, } -pub fn check_crate(tcx: ty::ctxt, crate: &Crate) { - visit::walk_crate(&mut CheckLoopVisitor { tcx: tcx }, - crate, - Context { in_loop: false, can_ret: true }); +pub fn check_crate(tcx: ty::ctxt, crate: &ast::Crate) { + visit::walk_crate(&mut CheckLoopVisitor { tcx: tcx }, crate, Normal) } impl Visitor for CheckLoopVisitor { - fn visit_item(&mut self, i:@item, _cx:Context) { - visit::walk_item(self, i, Context { - in_loop: false, - can_ret: true - }); + fn visit_item(&mut self, i: @ast::item, _cx: Context) { + visit::walk_item(self, i, Normal); } - fn visit_expr(&mut self, e:@Expr, cx:Context) { - - match e.node { - ExprWhile(e, ref b) => { + fn visit_expr(&mut self, e: @ast::Expr, cx:Context) { + match e.node { + ast::ExprWhile(e, ref b) => { self.visit_expr(e, cx); - self.visit_block(b, Context { in_loop: true,.. cx }); - } - ExprLoop(ref b, _) => { - self.visit_block(b, Context { in_loop: true,.. cx }); - } - ExprFnBlock(_, ref b) | ExprProc(_, ref b) => { - self.visit_block(b, Context { in_loop: false, can_ret: false }); - } - ExprBreak(_) => { - if !cx.in_loop { - self.tcx.sess.span_err(e.span, "`break` outside of loop"); - } - } - ExprAgain(_) => { - if !cx.in_loop { - self.tcx.sess.span_err(e.span, "`loop` outside of loop"); - } - } - ExprRet(oe) => { - if !cx.can_ret { - self.tcx.sess.span_err(e.span, "`return` in block function"); + self.visit_block(b, Loop); + } + ast::ExprLoop(ref b, _) => { + self.visit_block(b, Loop); + } + ast::ExprFnBlock(_, ref b) | ast::ExprProc(_, ref b) => { + self.visit_block(b, Closure); + } + ast::ExprBreak(_) => self.require_loop("break", cx, e.span), + ast::ExprAgain(_) => self.require_loop("continue", cx, e.span), + ast::ExprRet(oe) => { + if cx == Closure { + self.tcx.sess.span_err(e.span, "`return` in a closure"); } visit::walk_expr_opt(self, oe, cx); - } - _ => visit::walk_expr(self, e, cx) } + _ => visit::walk_expr(self, e, cx) + } + } +} +impl CheckLoopVisitor { + fn require_loop(&self, name: &str, cx: Context, span: Span) { + match cx { + Loop => {} + Closure => { + self.tcx.sess.span_err(span, format!("`{}` inside of a closure", + name)); + } + Normal => { + self.tcx.sess.span_err(span, format!("`{}` outside of loop", + name)); + } + } } } diff --git a/src/test/compile-fail/break-outside-loop.rs b/src/test/compile-fail/break-outside-loop.rs index b3154c9742aca..06281a5e2884b 100644 --- a/src/test/compile-fail/break-outside-loop.rs +++ b/src/test/compile-fail/break-outside-loop.rs @@ -8,15 +8,26 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`break` outside of loop - struct Foo { t: ~str } +fn cond() -> bool { true } + +fn foo(_: ||) {} + fn main() { - let pth = break; + let pth = break; //~ ERROR: `break` outside of loop + if cond() { continue } //~ ERROR: `continue` outside of loop - let rs: Foo = Foo{t: pth}; + while cond() { + if cond() { break } + if cond() { continue } + do foo { + if cond() { break } //~ ERROR: `break` inside of a closure + if cond() { continue } //~ ERROR: `continue` inside of a closure + } + } + let rs: Foo = Foo{t: pth}; } diff --git a/src/test/compile-fail/return-in-block-function.rs b/src/test/compile-fail/return-in-block-function.rs index 75a72f97204ef..f231810cbf117 100644 --- a/src/test/compile-fail/return-in-block-function.rs +++ b/src/test/compile-fail/return-in-block-function.rs @@ -10,6 +10,6 @@ fn main() { let _x = || { - return //~ ERROR: `return` in block function + return //~ ERROR: `return` in a closure }; }