@@ -21,6 +21,7 @@ use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
2121use rustc:: mir:: { ClearCrossCrate , Local , Location , Mir , Mutability , Operand , Place , PlaceBase } ;
2222use rustc:: mir:: { Field , ProjectionElem , Rvalue , Statement , StatementKind } ;
2323use rustc:: mir:: { Terminator , TerminatorKind } ;
24+ use rustc:: mir:: tcx:: PlaceTy ;
2425use rustc:: ty:: query:: Providers ;
2526use rustc:: ty:: { self , ParamEnv , TyCtxt , Ty } ;
2627
@@ -958,9 +959,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
958959 ty:: TyClosure ( def, substs) => {
959960 if let Place {
960961 base : PlaceBase :: Local ( local) ,
961- elems : _ ,
962+ elems,
962963 } = drop_place {
963- if * local == Local :: new ( 1 ) && !self . mir . upvar_decls . is_empty ( ) {
964+ if * local == Local :: new ( 1 )
965+ && !self . mir . upvar_decls . is_empty ( )
966+ && elems. is_empty ( ) {
964967 substs
965968 . upvar_tys ( def, self . tcx )
966969 . enumerate ( )
@@ -973,9 +976,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
973976 ty:: TyGenerator ( def, substs, _) => {
974977 if let Place {
975978 base : PlaceBase :: Local ( local) ,
976- elems : _ ,
979+ elems,
977980 } = drop_place {
978- if * local == Local :: new ( 1 ) && !self . mir . upvar_decls . is_empty ( ) {
981+ if * local == Local :: new ( 1 )
982+ && !self . mir . upvar_decls . is_empty ( )
983+ && elems. is_empty ( ) {
979984 substs
980985 . upvar_tys ( def, self . tcx )
981986 . enumerate ( )
@@ -1405,7 +1410,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
14051410 }
14061411
14071412 if let PlaceBase :: Local ( local) = place. base {
1408- self . used_mut . insert ( local) ;
1413+ if place. has_no_projection ( ) {
1414+ self . used_mut . insert ( local) ;
1415+ }
14091416 }
14101417 } ,
14111418 _ => { }
@@ -1488,7 +1495,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
14881495 // we'll have a memory leak) and assume that all statics have a destructor.
14891496 //
14901497 // FIXME: allow thread-locals to borrow other thread locals?
1491- let ( might_be_alive, will_be_dropped) = if !place. elems . is_empty ( ) {
1498+ let ( might_be_alive, will_be_dropped) = if !place. has_no_projection ( ) {
14921499 bug ! ( "root of {:?} is a projection ({:?})?" , place, place)
14931500 } else {
14941501 match place. base {
@@ -1769,7 +1776,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
17691776 place : & Place < ' tcx > ,
17701777 ) -> Result < MovePathIndex , NoMovePathFound > {
17711778 let mut prefix = place. clone ( ) ;
1772- if !prefix. elems . is_empty ( ) {
1779+ if !prefix. has_no_projection ( ) {
17731780 for ( i, _) in prefix. elems . iter ( ) . cloned ( ) . enumerate ( ) . rev ( ) {
17741781 prefix = place. elem_base ( self . tcx , i) ;
17751782 if let Some ( mpi) = self . move_path_for_place ( & prefix) {
@@ -1802,7 +1809,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18021809 flow_state : & Flows < ' cx , ' gcx , ' tcx > ,
18031810 ) {
18041811 debug ! ( "check_if_assigned_path_is_moved place: {:?}" , place) ;
1805- if !place. elems . is_empty ( ) {
1812+ if !place. has_no_projection ( ) {
18061813 let tcx = self . tcx ;
18071814 for ( i, elem) in place. elems . iter ( ) . cloned ( ) . enumerate ( ) . rev ( ) {
18081815 let base_place = place. elem_base ( tcx, i) ;
@@ -1988,7 +1995,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
19881995 is_local_mutation_allowed,
19891996 } = root_place;
19901997
1991- if !place. elems . is_empty ( ) {
1998+ if !place. has_no_projection ( ) {
19921999 if let Some ( field) = place. is_upvar_field_projection ( self . mir , & self . tcx ) {
19932000 self . used_mut_upvars . push ( field) ;
19942001 }
@@ -2068,17 +2075,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
20682075 is_local_mutation_allowed
20692076 ) ;
20702077
2071- if !place. elems . is_empty ( ) {
2072- let mut base_place = place. clone ( ) ;
2073- for ( i , elem) in place. elems. iter( ) . cloned ( ) . enumerate ( ) . rev ( ) {
2078+ if !place. has_no_projection ( ) {
2079+ let mut base_ty = place. base . ty ( self . mir ) ;
2080+ for elem in place. elems. iter ( ) {
20742081 result = match elem {
20752082 // NOTE(review): deref is really special.
20762083 //
20772084 // All other projections are owned by their base path, so mutable if
20782085 // base path is mutable
20792086 ProjectionElem : : Deref => {
2080- base_place = base_place . elem_base ( self . tcx , i ) ;
2081- let base_ty = base_place . ty ( self . mir , self . tcx ) . to_ty( self . tcx) ;
2087+ base_ty = PlaceTy :: from ( base_ty )
2088+ . projection_ty ( self . tcx , elem ) . to_ty( self . tcx) ;
20822089 match base_ty. sty {
20832090 ty : : TyRef ( _, _, mutbl) => {
20842091 match mutbl {
@@ -2101,8 +2108,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
21012108 }
21022109 _ => LocalMutationIsAllowed :: Yes ,
21032110 } ;
2104-
2105- continue ;
2111+ continue
21062112 }
21072113 }
21082114 }
@@ -2121,9 +2127,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
21212127 }
21222128 }
21232129 // `Box<T>` owns its content, so mutable if its location is mutable
2124- _ if base_ty. is_box ( ) => {
2125- continue ;
2126- }
2130+ _ if base_ty. is_box ( ) => { continue ; }
21272131 // Deref should only be for reference, pointers or boxes
21282132 _ => bug!( "Deref of unexpected type: {:?}" , base_ty) ,
21292133 }
@@ -2221,14 +2225,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
22212225
22222226 let mut deepest = place. clone ( ) ;
22232227
2224- if !place. elems . is_empty ( ) {
2228+ if !place. has_no_projection ( ) {
22252229 for ( i, elem) in place. elems . iter ( ) . cloned ( ) . enumerate ( ) . rev ( ) {
2226- deepest = match elem {
2230+ match elem {
22272231 ProjectionElem :: Deref
22282232 if place. ty ( self . mir , self . tcx ) . to_ty ( self . tcx ) . is_box ( ) => {
2229- place. elem_base ( self . tcx , i)
2233+ deepest = place. elem_base ( self . tcx , i) ;
22302234 } ,
2231- _ => continue ,
2235+ _ => { } ,
22322236 }
22332237 }
22342238 }
0 commit comments