@@ -236,7 +236,8 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
236236 if self . mode == Mode :: Fn {
237237 if let PlaceBase :: Local ( index) = dest. base {
238238 if self . mir . local_kind ( index) == LocalKind :: Temp
239- && self . temp_promotion_state [ index] . is_promotable ( ) {
239+ && self . temp_promotion_state [ index] . is_promotable ( )
240+ && dest. has_no_projection ( ) {
240241 debug ! ( "store to promotable temp {:?} ({:?})" , index, qualif) ;
241242 store ( & mut self . local_qualif [ index] ) ;
242243 }
@@ -249,6 +250,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
249250 if let PlaceBase :: Local ( index) = dest. base {
250251 if self . mir . local_kind ( index) == LocalKind :: Temp
251252 && self . mir . local_decls [ index] . ty . is_box ( )
253+ && dest. elems . len ( ) == 1
252254 && self . local_qualif [ index] . map_or ( false , |qualif| {
253255 qualif. contains ( Qualif :: NOT_CONST )
254256 } ) {
@@ -717,9 +719,21 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
717719 } else {
718720 // We might have a candidate for promotion.
719721 let candidate = Candidate :: Ref ( location) ;
722+ let mut tmp_place = place. clone ( ) ;
723+ for ( i, elem) in place. elems . iter ( ) . cloned ( ) . enumerate ( ) {
724+ match elem {
725+ ProjectionElem :: Deref => {
726+ break ;
727+ }
728+ _ => {
729+ tmp_place = place. elem_base ( self . tcx , i) ;
730+ }
731+ }
732+ }
720733
721- if let PlaceBase :: Local ( local) = place. base {
722- if self . mir . local_kind ( local) == LocalKind :: Temp {
734+ if let PlaceBase :: Local ( local) = tmp_place. base {
735+ if self . mir . local_kind ( local) == LocalKind :: Temp
736+ && tmp_place. has_no_projection ( ) {
723737 if let Some ( qualif) = self . local_qualif [ local] {
724738 // `forbidden_mut` is false, so we can safely ignore
725739 // `MUTABLE_INTERIOR` from the local's qualifications.
@@ -732,18 +746,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
732746 }
733747 }
734748 }
735-
736- // We can only promote interior borrows of promotable temps.
737- let mut place = place. clone ( ) ;
738- for ( i, elem) in place. elems . iter ( ) . cloned ( ) . enumerate ( ) . rev ( ) {
739- match elem {
740- ProjectionElem :: Deref => break ,
741- _ => {
742- place = place. elem_base ( self . tcx , i) ;
743- continue ;
744- }
745- }
746- }
747749 }
748750 }
749751
0 commit comments