about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-11-12 12:16:21 -0800
committerbors <bors@rust-lang.org>2013-11-12 12:16:21 -0800
commit3b0d48634f546055e17cf23a6bcde1bbfbc16b15 (patch)
tree277098c595ba15c5e5fd6c5c53b4e71f7649658b
parentf1a67bd4c0b3a8497f561144485ad757842a0078 (diff)
parent5fdbcc4020a440e18a3c570ffad5d2bb089c08db (diff)
downloadrust-3b0d48634f546055e17cf23a6bcde1bbfbc16b15.tar.gz
rust-3b0d48634f546055e17cf23a6bcde1bbfbc16b15.zip
auto merge of #10427 : alexcrichton/rust/no-xray, r=brson
Just a few triage issues that I ran into.
-rw-r--r--src/librustc/middle/check_loop.rs86
-rw-r--r--src/librustc/middle/resolve.rs28
-rw-r--r--src/test/compile-fail/break-outside-loop.rs19
-rw-r--r--src/test/compile-fail/return-in-block-function.rs2
4 files changed, 59 insertions, 76 deletions
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index a6aab151e5a..8a320f88649 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<Context> 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/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 23fef5e3516..4861fa19f7e 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,
diff --git a/src/test/compile-fail/break-outside-loop.rs b/src/test/compile-fail/break-outside-loop.rs
index b3154c9742a..06281a5e288 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 75a72f97204..f231810cbf1 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
     };
 }