about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2014-10-17 18:15:50 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2014-10-17 18:15:57 +0200
commit88de96178fd4d4eb214b5dce38759672ac15ec81 (patch)
treea118f98b3db8ee0cc0fc35b07e26591a9b13d9f5 /src
parent93e589c8726d91c084932af370742c15d97a0c24 (diff)
downloadrust-88de96178fd4d4eb214b5dce38759672ac15ec81.tar.gz
rust-88de96178fd4d4eb214b5dce38759672ac15ec81.zip
Check for borrow of local variable introduced within static block.
(Rather than ICE on it.)

Fix #18118.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/check_static.rs18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs
index 97acc74b8c6..42bc6452003 100644
--- a/src/librustc/middle/check_static.rs
+++ b/src/librustc/middle/check_static.rs
@@ -57,6 +57,7 @@ struct GlobalChecker {
     static_consumptions: NodeSet,
     const_borrows: NodeSet,
     static_interior_borrows: NodeSet,
+    static_local_borrows: NodeSet,
 }
 
 pub fn check_crate(tcx: &ty::ctxt) {
@@ -64,6 +65,7 @@ pub fn check_crate(tcx: &ty::ctxt) {
         static_consumptions: NodeSet::new(),
         const_borrows: NodeSet::new(),
         static_interior_borrows: NodeSet::new(),
+        static_local_borrows: NodeSet::new(),
     };
     {
         let visitor = euv::ExprUseVisitor::new(&mut checker, tcx);
@@ -200,6 +202,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
             }
         }
 
+        // local variables in a block expression in a static context (i.e. being
+        // assigned to a static variable) cannot be borrowed.
+        if self.checker.static_local_borrows.remove(&e.id) {
+            self.tcx.sess.span_err(e.span, "cannot borrow a local variable inside \
+                                            a static block, define a separate static \
+                                            instead");
+        }
+
         match e.node {
             ast::ExprAddrOf(ast::MutMutable, _) => {
                 if self.mode != InStaticMut {
@@ -298,8 +308,12 @@ impl euv::Delegate for GlobalChecker {
 
                 mc::cat_downcast(..) |
                 mc::cat_discr(..) |
-                mc::cat_upvar(..) |
-                mc::cat_local(..) => unreachable!(),
+                mc::cat_upvar(..) => unreachable!(),
+
+                mc::cat_local(..) => {
+                    self.static_local_borrows.insert(borrow_id);
+                    break
+                }
             }
         }
     }