@@ -41,6 +41,9 @@ use transform::{MirPass, MirSource};
41
41
use super :: promote_consts:: { self , Candidate , TempState } ;
42
42
43
43
bitflags ! {
44
+ // Borrows of temporaries can be promoted only if
45
+ // they have none of these qualifications, with
46
+ // the exception of `STATIC_REF` (in statics only).
44
47
struct Qualif : u8 {
45
48
// Constant containing interior mutability (UnsafeCell).
46
49
const MUTABLE_INTERIOR = 1 << 0 ;
@@ -65,10 +68,6 @@ bitflags! {
65
68
// promote_consts decided they weren't simple enough.
66
69
const NOT_PROMOTABLE = 1 << 6 ;
67
70
68
- // Borrows of temporaries can be promoted only
69
- // if they have none of the above qualifications.
70
- const NEVER_PROMOTE = 0b111_1111 ;
71
-
72
71
// Const items can only have MUTABLE_INTERIOR
73
72
// and NOT_PROMOTABLE without producing an error.
74
73
const CONST_ERROR = !Qualif :: MUTABLE_INTERIOR . bits &
@@ -197,7 +196,17 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
197
196
self . add ( original) ;
198
197
}
199
198
200
- /// Check if an Place with the current qualifications could
199
+ /// Check if a Local with the current qualifications is promotable.
200
+ fn can_promote ( & mut self ) -> bool {
201
+ // References to statics are allowed, but only in other statics.
202
+ if self . mode == Mode :: Static || self . mode == Mode :: StaticMut {
203
+ ( self . qualif - Qualif :: STATIC_REF ) . is_empty ( )
204
+ } else {
205
+ self . qualif . is_empty ( )
206
+ }
207
+ }
208
+
209
+ /// Check if a Place with the current qualifications could
201
210
/// be consumed, by either an operand or a Deref projection.
202
211
fn try_consume ( & mut self ) -> bool {
203
212
if self . qualif . intersects ( Qualif :: STATIC ) && self . mode != Mode :: Fn {
@@ -633,7 +642,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
633
642
634
643
// We might have a candidate for promotion.
635
644
let candidate = Candidate :: Ref ( location) ;
636
- if ! self . qualif . intersects ( Qualif :: NEVER_PROMOTE ) {
645
+ if self . can_promote ( ) {
637
646
// We can only promote direct borrows of temps.
638
647
if let Place :: Local ( local) = * place {
639
648
if self . mir . local_kind ( local) == LocalKind :: Temp {
@@ -745,7 +754,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
745
754
this. visit_operand ( arg, location) ;
746
755
if is_shuffle && i == 2 && this. mode == Mode :: Fn {
747
756
let candidate = Candidate :: ShuffleIndices ( bb) ;
748
- if ! this. qualif . intersects ( Qualif :: NEVER_PROMOTE ) {
757
+ if this. can_promote ( ) {
749
758
this. promotion_candidates . push ( candidate) ;
750
759
} else {
751
760
span_err ! ( this. tcx. sess, this. span, E0526 ,
0 commit comments