@@ -57,13 +57,15 @@ struct GlobalChecker {
57
57
static_consumptions : NodeSet ,
58
58
const_borrows : NodeSet ,
59
59
static_interior_borrows : NodeSet ,
60
+ static_local_borrows : NodeSet ,
60
61
}
61
62
62
63
pub fn check_crate ( tcx : & ty:: ctxt ) {
63
64
let mut checker = GlobalChecker {
64
65
static_consumptions : NodeSet :: new ( ) ,
65
66
const_borrows : NodeSet :: new ( ) ,
66
67
static_interior_borrows : NodeSet :: new ( ) ,
68
+ static_local_borrows : NodeSet :: new ( ) ,
67
69
} ;
68
70
{
69
71
let visitor = euv:: ExprUseVisitor :: new ( & mut checker, tcx) ;
@@ -200,6 +202,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
200
202
}
201
203
}
202
204
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
+
203
213
match e. node {
204
214
ast:: ExprAddrOf ( ast:: MutMutable , _) => {
205
215
if self . mode != InStaticMut {
@@ -298,8 +308,12 @@ impl euv::Delegate for GlobalChecker {
298
308
299
309
mc:: cat_downcast( ..) |
300
310
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
+ }
303
317
}
304
318
}
305
319
}
0 commit comments