@@ -161,29 +161,6 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt,
161
161
visit:: walk_local ( this, local, ( ) ) ;
162
162
}
163
163
164
- pub fn gather_loans_in_static_initializer ( bccx : & mut BorrowckCtxt , expr : & ast:: Expr ) {
165
-
166
- debug ! ( "gather_loans_in_item(expr={})" , expr. repr( bccx. tcx) ) ;
167
-
168
- let mut glcx = GatherLoanCtxt {
169
- bccx : bccx,
170
- id_range : IdRange :: max ( ) ,
171
- all_loans : Vec :: new ( ) ,
172
- item_ub : expr. id ,
173
- repeating_ids : vec ! ( expr. id) ,
174
- move_data : MoveData :: new ( )
175
- } ;
176
-
177
- // FIXME #13005 This should also walk the
178
- // expression.
179
- match expr. node {
180
- ast:: ExprAddrOf ( ..) => {
181
- glcx. visit_expr ( expr, ( ) ) ;
182
- }
183
- _ => { }
184
- }
185
- }
186
-
187
164
fn gather_loans_in_expr ( this : & mut GatherLoanCtxt ,
188
165
ex : & ast:: Expr ) {
189
166
let bccx = this. bccx ;
@@ -326,6 +303,58 @@ fn with_assignee_loan_path(bccx: &BorrowckCtxt, expr: &ast::Expr, op: |@LoanPath
326
303
}
327
304
}
328
305
306
+
307
+ /// Implements the A-* rules in doc.rs.
308
+ fn check_aliasability ( bccx : & BorrowckCtxt ,
309
+ borrow_span : Span ,
310
+ loan_cause : LoanCause ,
311
+ cmt : mc:: cmt ,
312
+ req_kind : ty:: BorrowKind )
313
+ -> Result < ( ) , ( ) > {
314
+
315
+ match ( cmt. freely_aliasable ( bccx. tcx ) , req_kind) {
316
+ ( None , _) => {
317
+ /* Uniquely accessible path -- OK for `&` and `&mut` */
318
+ Ok ( ( ) )
319
+ }
320
+ ( Some ( mc:: AliasableStatic ( safety) ) , ty:: ImmBorrow ) => {
321
+ // Borrow of an immutable static item:
322
+ match safety {
323
+ mc:: InteriorUnsafe => {
324
+ // If the static item contains an Unsafe<T>, it has interior mutability.
325
+ // In such cases, we cannot permit it to be borrowed, because the
326
+ // static item resides in immutable memory and mutating it would
327
+ // cause segfaults.
328
+ bccx. tcx . sess . span_err ( borrow_span,
329
+ format ! ( "borrow of immutable static items with \
330
+ unsafe interior is not allowed") ) ;
331
+ Err ( ( ) )
332
+ }
333
+ mc:: InteriorSafe => {
334
+ // Immutable static can be borrowed, no problem.
335
+ Ok ( ( ) )
336
+ }
337
+ }
338
+ }
339
+ ( Some ( mc:: AliasableStaticMut ( ..) ) , _) => {
340
+ // Even touching a static mut is considered unsafe. We assume the
341
+ // user knows what they're doing in these cases.
342
+ Ok ( ( ) )
343
+ }
344
+ ( Some ( alias_cause) , ty:: UniqueImmBorrow ) |
345
+ ( Some ( alias_cause) , ty:: MutBorrow ) => {
346
+ bccx. report_aliasability_violation (
347
+ borrow_span,
348
+ BorrowViolation ( loan_cause) ,
349
+ alias_cause) ;
350
+ Err ( ( ) )
351
+ }
352
+ ( _, _) => {
353
+ Ok ( ( ) )
354
+ }
355
+ }
356
+ }
357
+
329
358
impl < ' a > GatherLoanCtxt < ' a > {
330
359
pub fn tcx ( & self ) -> & ' a ty:: ctxt { self . bccx . tcx }
331
360
@@ -676,57 +705,6 @@ impl<'a> GatherLoanCtxt<'a> {
676
705
}
677
706
}
678
707
}
679
-
680
- fn check_aliasability ( bccx : & BorrowckCtxt ,
681
- borrow_span : Span ,
682
- loan_cause : LoanCause ,
683
- cmt : mc:: cmt ,
684
- req_kind : ty:: BorrowKind )
685
- -> Result < ( ) , ( ) > {
686
- //! Implements the A-* rules in doc.rs.
687
-
688
- match ( cmt. freely_aliasable ( bccx. tcx ) , req_kind) {
689
- ( None , _) => {
690
- /* Uniquely accessible path -- OK for `&` and `&mut` */
691
- Ok ( ( ) )
692
- }
693
- ( Some ( mc:: AliasableStatic ( safety) ) , ty:: ImmBorrow ) => {
694
- // Borrow of an immutable static item:
695
- match safety {
696
- mc:: InteriorUnsafe => {
697
- // If the static item contains an Unsafe<T>, it has interior mutability.
698
- // In such cases, we cannot permit it to be borrowed, because the
699
- // static item resides in immutable memory and mutating it would
700
- // cause segfaults.
701
- bccx. tcx . sess . span_err ( borrow_span,
702
- format ! ( "borrow of immutable static items with \
703
- unsafe interior is not allowed") ) ;
704
- Err ( ( ) )
705
- }
706
- mc:: InteriorSafe => {
707
- // Immutable static can be borrowed, no problem.
708
- Ok ( ( ) )
709
- }
710
- }
711
- }
712
- ( Some ( mc:: AliasableStaticMut ( ..) ) , _) => {
713
- // Even touching a static mut is considered unsafe. We assume the
714
- // user knows what they're doing in these cases.
715
- Ok ( ( ) )
716
- }
717
- ( Some ( alias_cause) , ty:: UniqueImmBorrow ) |
718
- ( Some ( alias_cause) , ty:: MutBorrow ) => {
719
- bccx. report_aliasability_violation (
720
- borrow_span,
721
- BorrowViolation ( loan_cause) ,
722
- alias_cause) ;
723
- Err ( ( ) )
724
- }
725
- ( _, _) => {
726
- Ok ( ( ) )
727
- }
728
- }
729
- }
730
708
}
731
709
732
710
fn restriction_set ( & self , req_kind : ty:: BorrowKind ) -> RestrictionSet {
@@ -948,3 +926,44 @@ impl<'a> GatherLoanCtxt<'a> {
948
926
pat_util:: pat_is_binding ( self . bccx . tcx . def_map , pat)
949
927
}
950
928
}
929
+
930
+ /// Context used while gathering loans on static initializers
931
+ ///
932
+ /// This visitor walks static initializer's expressions and makes
933
+ /// sure the loans being taken are sound.
934
+ struct StaticInitializerCtxt < ' a > {
935
+ bccx : & ' a BorrowckCtxt < ' a > ,
936
+ id_range : IdRange ,
937
+ item_ub : ast:: NodeId ,
938
+ }
939
+
940
+ impl < ' a > visit:: Visitor < ( ) > for StaticInitializerCtxt < ' a > {
941
+ fn visit_expr ( & mut self , ex : & Expr , _: ( ) ) {
942
+ match ex. node {
943
+ ast:: ExprAddrOf ( mutbl, base) => {
944
+ let base_cmt = self . bccx . cat_expr ( base) ;
945
+ let borrow_kind = ty:: BorrowKind :: from_mutbl ( mutbl) ;
946
+ // Check that we don't allow borrows of unsafe static items.
947
+ if check_aliasability ( self . bccx , ex. span , AddrOf , base_cmt, borrow_kind) . is_err ( ) {
948
+ return ; // reported an error, no sense in reporting more.
949
+ }
950
+ }
951
+ _ => { }
952
+ }
953
+
954
+ visit:: walk_expr ( self , ex, ( ) ) ;
955
+ }
956
+ }
957
+
958
+ pub fn gather_loans_in_static_initializer ( bccx : & mut BorrowckCtxt , expr : & ast:: Expr ) {
959
+
960
+ debug ! ( "gather_loans_in_static_initializer(expr={})" , expr. repr( bccx. tcx) ) ;
961
+
962
+ let mut sicx = StaticInitializerCtxt {
963
+ bccx : bccx,
964
+ id_range : IdRange :: max ( ) ,
965
+ item_ub : expr. id ,
966
+ } ;
967
+
968
+ sicx. visit_expr ( expr, ( ) ) ;
969
+ }
0 commit comments