@@ -229,12 +229,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
229229 }
230230
231231 /// 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 {
233233 // References to statics are allowed, but only in other statics.
234234 if self . mode == Mode :: Static || self . mode == Mode :: StaticMut {
235- ( self . qualif - Qualif :: STATIC_REF ) . is_empty ( )
235+ ( qualif - Qualif :: STATIC_REF ) . is_empty ( )
236236 } else {
237- self . qualif . is_empty ( )
237+ qualif. is_empty ( )
238238 }
239239 }
240240
@@ -746,10 +746,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
746746
747747 if forbidden_mut {
748748 self . add ( Qualif :: NOT_CONST ) ;
749- } else if self . can_promote ( ) {
749+ } else {
750750 // We might have a candidate for promotion.
751751 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.
753753 let mut place = place;
754754 while let Place :: Projection ( ref proj) = * place {
755755 if proj. elem == ProjectionElem :: Deref {
@@ -760,7 +760,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
760760 if let Place :: Local ( local) = * place {
761761 if self . mir . local_kind ( local) == LocalKind :: Temp {
762762 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 ) {
764769 self . promotion_candidates . push ( candidate) ;
765770 }
766771 }
@@ -920,7 +925,7 @@ This does not pose a problem by itself because they can't be accessed directly."
920925 }
921926 let candidate = Candidate :: Argument { bb, index : i } ;
922927 if is_shuffle && i == 2 {
923- if this. can_promote ( ) {
928+ if this. can_promote ( this . qualif ) {
924929 this. promotion_candidates . push ( candidate) ;
925930 } else {
926931 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."
936941 if !constant_arguments. contains ( & i) {
937942 return
938943 }
939- if this. can_promote ( ) {
944+ if this. can_promote ( this . qualif ) {
940945 this. promotion_candidates . push ( candidate) ;
941946 } else {
942947 this. tcx . sess . span_err ( this. span ,
0 commit comments