@@ -57,13 +57,15 @@ struct GlobalChecker {
5757 static_consumptions : NodeSet ,
5858 const_borrows : NodeSet ,
5959 static_interior_borrows : NodeSet ,
60+ static_local_borrows : NodeSet ,
6061}
6162
6263pub fn check_crate ( tcx : & ty:: ctxt ) {
6364 let mut checker = GlobalChecker {
6465 static_consumptions : NodeSet :: new ( ) ,
6566 const_borrows : NodeSet :: new ( ) ,
6667 static_interior_borrows : NodeSet :: new ( ) ,
68+ static_local_borrows : NodeSet :: new ( ) ,
6769 } ;
6870 {
6971 let visitor = euv:: ExprUseVisitor :: new ( & mut checker, tcx) ;
@@ -200,6 +202,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
200202 }
201203 }
202204
205+ // local variables in a block expression in a static context (i.e. being
206+ // assigned to a static variable) cannot be borrowed.
207+ if self . checker . static_local_borrows . remove ( & e. id ) {
208+ self . tcx . sess . span_err ( e. span , "cannot borrow a local variable inside \
209+ a static block, define a separate static \
210+ instead") ;
211+ }
212+
203213 match e. node {
204214 ast:: ExprAddrOf ( ast:: MutMutable , _) => {
205215 if self . mode != InStaticMut {
@@ -298,8 +308,12 @@ impl euv::Delegate for GlobalChecker {
298308
299309 mc:: cat_downcast( ..) |
300310 mc:: cat_discr( ..) |
301- mc:: cat_upvar( ..) |
302- mc:: cat_local( ..) => unreachable ! ( ) ,
311+ mc:: cat_upvar( ..) => unreachable ! ( ) ,
312+
313+ mc:: cat_local( ..) => {
314+ self . static_local_borrows . insert ( borrow_id) ;
315+ break
316+ }
303317 }
304318 }
305319 }
0 commit comments