@@ -161,29 +161,6 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt,
161161 visit:: walk_local ( this, local, ( ) ) ;
162162}
163163
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-
187164fn gather_loans_in_expr ( this : & mut GatherLoanCtxt ,
188165 ex : & ast:: Expr ) {
189166 let bccx = this. bccx ;
@@ -326,6 +303,58 @@ fn with_assignee_loan_path(bccx: &BorrowckCtxt, expr: &ast::Expr, op: |@LoanPath
326303 }
327304}
328305
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+
329358impl < ' a > GatherLoanCtxt < ' a > {
330359 pub fn tcx ( & self ) -> & ' a ty:: ctxt { self . bccx . tcx }
331360
@@ -676,57 +705,6 @@ impl<'a> GatherLoanCtxt<'a> {
676705 }
677706 }
678707 }
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- }
730708 }
731709
732710 fn restriction_set ( & self , req_kind : ty:: BorrowKind ) -> RestrictionSet {
@@ -948,3 +926,44 @@ impl<'a> GatherLoanCtxt<'a> {
948926 pat_util:: pat_is_binding ( self . bccx . tcx . def_map , pat)
949927 }
950928}
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