@@ -229,12 +229,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
229
229
}
230
230
231
231
/// Check if a Local with the current qualifications is promotable.
232
- fn can_promote ( & mut self ) -> bool {
232
+ fn can_promote ( & self , qualif : Qualif ) -> bool {
233
233
// References to statics are allowed, but only in other statics.
234
234
if self . mode == Mode :: Static || self . mode == Mode :: StaticMut {
235
- ( self . qualif - Qualif :: STATIC_REF ) . is_empty ( )
235
+ ( qualif - Qualif :: STATIC_REF ) . is_empty ( )
236
236
} else {
237
- self . qualif . is_empty ( )
237
+ qualif. is_empty ( )
238
238
}
239
239
}
240
240
@@ -746,10 +746,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
746
746
747
747
if forbidden_mut {
748
748
self . add ( Qualif :: NOT_CONST ) ;
749
- } else if self . can_promote ( ) {
749
+ } else {
750
750
// We might have a candidate for promotion.
751
751
let candidate = Candidate :: Ref ( location) ;
752
- // We can only promote interior borrows of non-drop temps.
752
+ // We can only promote interior borrows of promotable temps.
753
753
let mut place = place;
754
754
while let Place :: Projection ( ref proj) = * place {
755
755
if proj. elem == ProjectionElem :: Deref {
@@ -760,7 +760,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
760
760
if let Place :: Local ( local) = * place {
761
761
if self . mir . local_kind ( local) == LocalKind :: Temp {
762
762
if let Some ( qualif) = self . temp_qualif [ local] {
763
- if !qualif. intersects ( Qualif :: NEEDS_DROP ) {
763
+ // `forbidden_mut` is false, so we can safely ignore
764
+ // `MUTABLE_INTERIOR` from the local's qualifications.
765
+ // This allows borrowing fields which don't have
766
+ // `MUTABLE_INTERIOR`, from a type that does, e.g.:
767
+ // `let _: &'static _ = &(Cell::new(1), 2).1;`
768
+ if self . can_promote ( qualif - Qualif :: MUTABLE_INTERIOR ) {
764
769
self . promotion_candidates . push ( candidate) ;
765
770
}
766
771
}
@@ -920,7 +925,7 @@ This does not pose a problem by itself because they can't be accessed directly."
920
925
}
921
926
let candidate = Candidate :: Argument { bb, index : i } ;
922
927
if is_shuffle && i == 2 {
923
- if this. can_promote ( ) {
928
+ if this. can_promote ( this . qualif ) {
924
929
this. promotion_candidates . push ( candidate) ;
925
930
} else {
926
931
span_err ! ( this. tcx. sess, this. span, E0526 ,
@@ -936,7 +941,7 @@ This does not pose a problem by itself because they can't be accessed directly."
936
941
if !constant_arguments. contains ( & i) {
937
942
return
938
943
}
939
- if this. can_promote ( ) {
944
+ if this. can_promote ( this . qualif ) {
940
945
this. promotion_candidates . push ( candidate) ;
941
946
} else {
942
947
this. tcx . sess . span_err ( this. span ,
0 commit comments