@@ -476,35 +476,27 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
476476 }
477477 }
478478
479- Rvalue :: Ref ( _, BorrowKind :: Mut { .. } , place) => {
480- let ty = place. ty ( self . body , self . tcx ) . ty ;
481- let is_allowed = match ty. kind ( ) {
482- // Inside a `static mut`, `&mut [...]` is allowed.
483- ty:: Array ( ..) | ty:: Slice ( _)
484- if self . const_kind ( ) == hir:: ConstContext :: Static ( hir:: Mutability :: Mut ) =>
485- {
486- true
487- }
488-
489- // FIXME(ecstaticmorse): We could allow `&mut []` inside a const context given
490- // that this is merely a ZST and it is already eligible for promotion.
491- // This may require an RFC?
492- /*
493- ty::Array(_, len) if len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(0)
494- => true,
495- */
496- _ => false ,
497- } ;
479+ Rvalue :: Ref ( _, BorrowKind :: Mut { .. } , place)
480+ | Rvalue :: AddressOf ( Mutability :: Mut , place) => {
481+ // Inside mutable statics, we allow arbitrary mutable references.
482+ // We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
483+ // reasons why are lost to history), and there is no reason to restrict that to
484+ // arrays and slices.
485+ let is_allowed =
486+ self . const_kind ( ) == hir:: ConstContext :: Static ( hir:: Mutability :: Mut ) ;
498487
499488 if !is_allowed {
500- self . check_mut_borrow ( place. local , hir:: BorrowKind :: Ref )
489+ self . check_mut_borrow (
490+ place. local ,
491+ if matches ! ( rvalue, Rvalue :: Ref ( ..) ) {
492+ hir:: BorrowKind :: Ref
493+ } else {
494+ hir:: BorrowKind :: Raw
495+ } ,
496+ ) ;
501497 }
502498 }
503499
504- Rvalue :: AddressOf ( Mutability :: Mut , place) => {
505- self . check_mut_borrow ( place. local , hir:: BorrowKind :: Raw )
506- }
507-
508500 Rvalue :: Ref ( _, BorrowKind :: Shared | BorrowKind :: Fake , place)
509501 | Rvalue :: AddressOf ( Mutability :: Not , place) => {
510502 let borrowed_place_has_mut_interior = qualifs:: in_place :: < HasMutInterior , _ > (
0 commit comments