@@ -9,8 +9,9 @@ use rustc::mir::{
99 self , AggregateKind , BindingForm , BorrowKind , ClearCrossCrate , Constant ,
1010 ConstraintCategory , Field , Local , LocalDecl , LocalKind , Location , Operand ,
1111 Place , PlaceProjection , ProjectionElem , Rvalue , Statement , StatementKind ,
12- TerminatorKind , VarBindingForm ,
12+ TerminatorKind , VarBindingForm , NeoPlace , NeoPlaceTree , PlaceBase ,
1313} ;
14+ use rustc:: mir:: tcx:: PlaceTy ;
1415use rustc:: ty:: { self , DefIdTree } ;
1516use rustc:: util:: ppaux:: RegionHighlightMode ;
1617use rustc_data_structures:: fx:: FxHashSet ;
@@ -1570,37 +1571,39 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
15701571 place : & Place < ' tcx > ,
15711572 including_downcast : IncludingDowncast ,
15721573 ) -> Option < String > {
1574+ let neo_place = self . infcx . tcx . as_new_place ( place) ;
15731575 let mut buf = String :: new ( ) ;
1574- match self . append_place_to_string ( place, & mut buf, false , & including_downcast) {
1575- Ok ( ( ) ) => Some ( buf) ,
1576- Err ( ( ) ) => None ,
1577- }
1576+ self . append_place_to_string (
1577+ & neo_place,
1578+ & mut buf,
1579+ false ,
1580+ & including_downcast
1581+ ) . and ( Ok ( buf) ) . ok ( )
15781582 }
15791583
15801584 /// Appends end-user visible description of `place` to `buf`.
15811585 fn append_place_to_string (
15821586 & self ,
1583- place : & Place < ' tcx > ,
1587+ place : & NeoPlace < ' tcx > ,
15841588 buf : & mut String ,
15851589 mut autoderef : bool ,
15861590 including_downcast : & IncludingDowncast ,
15871591 ) -> Result < ( ) , ( ) > {
1588- match * place {
1589- Place :: Promoted ( _) => {
1592+ match place. clone ( ) . into_tree ( ) {
1593+ NeoPlaceTree :: Base ( PlaceBase :: Promoted ( _) ) => {
15901594 buf. push_str ( "promoted" ) ;
15911595 }
1592- Place :: Local ( local) => {
1596+ NeoPlaceTree :: Base ( PlaceBase :: Local ( local) ) => {
15931597 self . append_local_to_string ( local, buf) ?;
15941598 }
1595- Place :: Static ( ref static_) => {
1599+ NeoPlaceTree :: Base ( PlaceBase :: Static ( ref static_) ) => {
15961600 buf. push_str ( & self . infcx . tcx . item_name ( static_. def_id ) . to_string ( ) ) ;
15971601 }
1598- Place :: Projection ( ref proj) => {
1602+ NeoPlaceTree :: Projected ( proj) => {
15991603 match proj. elem {
16001604 ProjectionElem :: Deref => {
1601- let neo_place = self . infcx . tcx . as_new_place ( place) ;
16021605 let upvar_field_projection =
1603- neo_place . is_upvar_field_projection ( self . mir , & self . infcx . tcx ) ;
1606+ place . is_upvar_field_projection ( self . mir , & self . infcx . tcx ) ;
16041607 if let Some ( field) = upvar_field_projection {
16051608 let var_index = field. index ( ) ;
16061609 let name = self . mir . upvar_decls [ var_index] . debug_name . to_string ( ) ;
@@ -1617,7 +1620,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16171620 autoderef,
16181621 & including_downcast,
16191622 ) ?;
1620- } else if let Place :: Local ( local) = proj. base {
1623+ } else if let Some ( local) = proj. base . as_local ( ) {
16211624 if let Some ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) =
16221625 self . mir . local_decls [ local] . is_user_variable
16231626 {
@@ -1660,9 +1663,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16601663 }
16611664 ProjectionElem :: Field ( field, _ty) => {
16621665 autoderef = true ;
1663- let neo_place = self . infcx . tcx . as_new_place ( place) ;
16641666 let upvar_field_projection =
1665- neo_place . is_upvar_field_projection ( self . mir , & self . infcx . tcx ) ;
1667+ place . is_upvar_field_projection ( self . mir , & self . infcx . tcx ) ;
16661668 if let Some ( field) = upvar_field_projection {
16671669 let var_index = field. index ( ) ;
16681670 let name = self . mir . upvar_decls [ var_index] . debug_name . to_string ( ) ;
@@ -1727,15 +1729,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
17271729 }
17281730
17291731 /// End-user visible description of the `field`nth field of `base`
1730- fn describe_field ( & self , base : & Place , field : Field ) -> String {
1731- match * base {
1732- Place :: Local ( local) => {
1732+ fn describe_field ( & self , base : & NeoPlace < ' tcx > , field : Field ) -> String {
1733+ match base. clone ( ) . into_tree ( ) {
1734+ NeoPlaceTree :: Base ( PlaceBase :: Local ( local) ) => {
17331735 let local = & self . mir . local_decls [ local] ;
17341736 self . describe_field_from_ty ( & local. ty , field)
17351737 }
1736- Place :: Promoted ( ref prom) => self . describe_field_from_ty ( & prom. 1 , field) ,
1737- Place :: Static ( ref static_) => self . describe_field_from_ty ( & static_. ty , field) ,
1738- Place :: Projection ( ref proj) => match proj. elem {
1738+ NeoPlaceTree :: Base ( PlaceBase :: Promoted ( ref prom) ) =>
1739+ self . describe_field_from_ty ( & prom. 1 , field) ,
1740+ NeoPlaceTree :: Base ( PlaceBase :: Static ( ref static_) ) =>
1741+ self . describe_field_from_ty ( & static_. ty , field) ,
1742+ NeoPlaceTree :: Projected ( ref proj) => match proj. elem {
17391743 ProjectionElem :: Deref => self . describe_field ( & proj. base , field) ,
17401744 ProjectionElem :: Downcast ( def, variant_index) =>
17411745 def. variants [ variant_index] . fields [ field. index ( ) ] . ident . to_string ( ) ,
@@ -1796,7 +1800,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
17961800
17971801 /// Check if a place is a thread-local static.
17981802 pub fn is_place_thread_local ( & self , place : & Place < ' tcx > ) -> bool {
1799- if let Place :: Static ( statik) = place {
1803+ let neo_place = self . infcx . tcx . as_new_place ( place) ;
1804+ if let Some ( PlaceBase :: Static ( statik) ) = neo_place. as_place_base ( ) {
18001805 let attrs = self . infcx . tcx . get_attrs ( statik. def_id ) ;
18011806 let is_thread_local = attrs. iter ( ) . any ( |attr| attr. check_name ( "thread_local" ) ) ;
18021807
@@ -1813,47 +1818,45 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18131818
18141819 fn classify_drop_access_kind ( & self , place : & Place < ' tcx > ) -> StorageDeadOrDrop < ' tcx > {
18151820 let tcx = self . infcx . tcx ;
1816- match place {
1817- Place :: Local ( _) | Place :: Static ( _) | Place :: Promoted ( _) => {
1818- StorageDeadOrDrop :: LocalStorageDead
1819- }
1820- Place :: Projection ( box PlaceProjection { base, elem } ) => {
1821- let base_access = self . classify_drop_access_kind ( base) ;
1822- match elem {
1823- ProjectionElem :: Deref => match base_access {
1824- StorageDeadOrDrop :: LocalStorageDead
1825- | StorageDeadOrDrop :: BoxedStorageDead => {
1826- assert ! (
1827- base. ty( self . mir, tcx) . to_ty( tcx) . is_box( ) ,
1828- "Drop of value behind a reference or raw pointer"
1829- ) ;
1830- StorageDeadOrDrop :: BoxedStorageDead
1831- }
1832- StorageDeadOrDrop :: Destructor ( _) => base_access,
1833- } ,
1834- ProjectionElem :: Field ( ..) | ProjectionElem :: Downcast ( ..) => {
1835- let base_ty = base. ty ( self . mir , tcx) . to_ty ( tcx) ;
1836- match base_ty. sty {
1837- ty:: Adt ( def, _) if def. has_dtor ( tcx) => {
1838- // Report the outermost adt with a destructor
1839- match base_access {
1840- StorageDeadOrDrop :: Destructor ( _) => base_access,
1841- StorageDeadOrDrop :: LocalStorageDead
1842- | StorageDeadOrDrop :: BoxedStorageDead => {
1843- StorageDeadOrDrop :: Destructor ( base_ty)
1844- }
1821+ let place = tcx. as_new_place ( place) ;
1822+ let mut access = StorageDeadOrDrop :: LocalStorageDead ;
1823+ let mut base_ty = place. base . ty ( self . mir ) ;
1824+ for elem in place. elems . iter ( ) {
1825+ match elem {
1826+ ProjectionElem :: Deref => match access {
1827+ StorageDeadOrDrop :: LocalStorageDead
1828+ | StorageDeadOrDrop :: BoxedStorageDead => {
1829+ assert ! (
1830+ base_ty. is_box( ) ,
1831+ "Drop of value behind a reference or raw pointer"
1832+ ) ;
1833+ access = StorageDeadOrDrop :: BoxedStorageDead ;
1834+ }
1835+ StorageDeadOrDrop :: Destructor ( _) => { } ,
1836+ } ,
1837+ ProjectionElem :: Field ( ..) | ProjectionElem :: Downcast ( ..) => {
1838+ match base_ty. sty {
1839+ ty:: Adt ( def, _) if def. has_dtor ( tcx) => {
1840+ // Report the outermost adt with a destructor
1841+ match access {
1842+ StorageDeadOrDrop :: Destructor ( _) => { } ,
1843+ StorageDeadOrDrop :: LocalStorageDead
1844+ | StorageDeadOrDrop :: BoxedStorageDead => {
1845+ access = StorageDeadOrDrop :: Destructor ( base_ty) ;
18451846 }
18461847 }
1847- _ => base_access,
18481848 }
1849+ _ => { } ,
18491850 }
1850-
1851- ProjectionElem :: ConstantIndex { .. }
1852- | ProjectionElem :: Subslice { .. }
1853- | ProjectionElem :: Index ( _) => base_access,
18541851 }
1852+
1853+ ProjectionElem :: ConstantIndex { .. }
1854+ | ProjectionElem :: Subslice { .. }
1855+ | ProjectionElem :: Index ( _) => { } ,
18551856 }
1857+ base_ty = PlaceTy :: from ( base_ty) . projection_ty ( tcx, elem) . to_ty ( tcx) ;
18561858 }
1859+ access
18571860 }
18581861
18591862 /// Annotate argument and return type of function and closure with (synthesized) lifetime for
@@ -1897,9 +1900,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18971900 "annotate_argument_and_return_for_borrow: reservation={:?}" ,
18981901 reservation
18991902 ) ;
1903+ let reservation = self . infcx . tcx . as_new_place ( reservation) ;
19001904 // Check that the initial assignment of the reserve location is into a temporary.
1901- let mut target = * match reservation {
1902- Place :: Local ( local) if self . mir . local_kind ( * local) == LocalKind :: Temp => local,
1905+ let mut target = match reservation. as_local ( ) {
1906+ Some ( local) if self . mir . local_kind ( local) == LocalKind :: Temp => local,
19031907 _ => return None ,
19041908 } ;
19051909
0 commit comments