@@ -471,35 +471,21 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
471471 }
472472 }
473473
474- Rvalue :: Ref ( _, BorrowKind :: Mut { .. } , place) => {
475- let ty = place. ty ( self . body , self . tcx ) . ty ;
476- let is_allowed = match ty. kind ( ) {
477- // Inside a `static mut`, `&mut [...]` is allowed.
478- ty:: Array ( ..) | ty:: Slice ( _)
479- if self . const_kind ( ) == hir:: ConstContext :: Static ( hir:: Mutability :: Mut ) =>
480- {
481- true
482- }
483-
484- // FIXME(ecstaticmorse): We could allow `&mut []` inside a const context given
485- // that this is merely a ZST and it is already eligible for promotion.
486- // This may require an RFC?
487- /*
488- ty::Array(_, len) if len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(0)
489- => true,
490- */
491- _ => false ,
492- } ;
474+ Rvalue :: Ref ( _, BorrowKind :: Mut { .. } , place) | Rvalue :: AddressOf ( Mutability :: Mut , place) => {
475+ // Inside mutable statics, we allow arbitrary mutable references.
476+ // We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
477+ // reasons why are lost to history), and there is no reason to restrict that to
478+ // arrays and slices.
479+ let is_allowed = self . const_kind ( ) == hir:: ConstContext :: Static ( hir:: Mutability :: Mut ) ;
493480
494481 if !is_allowed {
495- self . check_mut_borrow ( place. local , hir:: BorrowKind :: Ref )
482+ self . check_mut_borrow (
483+ place. local ,
484+ if matches ! ( rvalue, Rvalue :: Ref ( ..) ) { hir:: BorrowKind :: Ref } else { hir:: BorrowKind :: Raw }
485+ ) ;
496486 }
497487 }
498488
499- Rvalue :: AddressOf ( Mutability :: Mut , place) => {
500- self . check_mut_borrow ( place. local , hir:: BorrowKind :: Raw )
501- }
502-
503489 Rvalue :: Ref ( _, BorrowKind :: Shared | BorrowKind :: Shallow , place)
504490 | Rvalue :: AddressOf ( Mutability :: Not , place) => {
505491 let borrowed_place_has_mut_interior = qualifs:: in_place :: < HasMutInterior , _ > (
0 commit comments