@@ -9,8 +9,9 @@ use rustc::mir::{
9
9
self , AggregateKind , BindingForm , BorrowKind , ClearCrossCrate , Constant ,
10
10
ConstraintCategory , Field , Local , LocalDecl , LocalKind , Location , Operand ,
11
11
Place , PlaceProjection , ProjectionElem , Rvalue , Statement , StatementKind ,
12
- TerminatorKind , VarBindingForm ,
12
+ TerminatorKind , VarBindingForm , NeoPlace , NeoPlaceTree , PlaceBase ,
13
13
} ;
14
+ use rustc:: mir:: tcx:: PlaceTy ;
14
15
use rustc:: ty:: { self , DefIdTree } ;
15
16
use rustc:: util:: ppaux:: RegionHighlightMode ;
16
17
use rustc_data_structures:: fx:: FxHashSet ;
@@ -1570,37 +1571,39 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1570
1571
place : & Place < ' tcx > ,
1571
1572
including_downcast : IncludingDowncast ,
1572
1573
) -> Option < String > {
1574
+ let neo_place = self . infcx . tcx . as_new_place ( place) ;
1573
1575
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 ( )
1578
1582
}
1579
1583
1580
1584
/// Appends end-user visible description of `place` to `buf`.
1581
1585
fn append_place_to_string (
1582
1586
& self ,
1583
- place : & Place < ' tcx > ,
1587
+ place : & NeoPlace < ' tcx > ,
1584
1588
buf : & mut String ,
1585
1589
mut autoderef : bool ,
1586
1590
including_downcast : & IncludingDowncast ,
1587
1591
) -> Result < ( ) , ( ) > {
1588
- match * place {
1589
- Place :: Promoted ( _) => {
1592
+ match place. clone ( ) . into_tree ( ) {
1593
+ NeoPlaceTree :: Base ( PlaceBase :: Promoted ( _) ) => {
1590
1594
buf. push_str ( "promoted" ) ;
1591
1595
}
1592
- Place :: Local ( local) => {
1596
+ NeoPlaceTree :: Base ( PlaceBase :: Local ( local) ) => {
1593
1597
self . append_local_to_string ( local, buf) ?;
1594
1598
}
1595
- Place :: Static ( ref static_) => {
1599
+ NeoPlaceTree :: Base ( PlaceBase :: Static ( ref static_) ) => {
1596
1600
buf. push_str ( & self . infcx . tcx . item_name ( static_. def_id ) . to_string ( ) ) ;
1597
1601
}
1598
- Place :: Projection ( ref proj) => {
1602
+ NeoPlaceTree :: Projected ( proj) => {
1599
1603
match proj. elem {
1600
1604
ProjectionElem :: Deref => {
1601
- let neo_place = self . infcx . tcx . as_new_place ( place) ;
1602
1605
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 ) ;
1604
1607
if let Some ( field) = upvar_field_projection {
1605
1608
let var_index = field. index ( ) ;
1606
1609
let name = self . mir . upvar_decls [ var_index] . debug_name . to_string ( ) ;
@@ -1617,7 +1620,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1617
1620
autoderef,
1618
1621
& including_downcast,
1619
1622
) ?;
1620
- } else if let Place :: Local ( local) = proj. base {
1623
+ } else if let Some ( local) = proj. base . as_local ( ) {
1621
1624
if let Some ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) =
1622
1625
self . mir . local_decls [ local] . is_user_variable
1623
1626
{
@@ -1660,9 +1663,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1660
1663
}
1661
1664
ProjectionElem :: Field ( field, _ty) => {
1662
1665
autoderef = true ;
1663
- let neo_place = self . infcx . tcx . as_new_place ( place) ;
1664
1666
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 ) ;
1666
1668
if let Some ( field) = upvar_field_projection {
1667
1669
let var_index = field. index ( ) ;
1668
1670
let name = self . mir . upvar_decls [ var_index] . debug_name . to_string ( ) ;
@@ -1727,15 +1729,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1727
1729
}
1728
1730
1729
1731
/// 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) ) => {
1733
1735
let local = & self . mir . local_decls [ local] ;
1734
1736
self . describe_field_from_ty ( & local. ty , field)
1735
1737
}
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 {
1739
1743
ProjectionElem :: Deref => self . describe_field ( & proj. base , field) ,
1740
1744
ProjectionElem :: Downcast ( def, variant_index) =>
1741
1745
def. variants [ variant_index] . fields [ field. index ( ) ] . ident . to_string ( ) ,
@@ -1796,7 +1800,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1796
1800
1797
1801
/// Check if a place is a thread-local static.
1798
1802
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 ( ) {
1800
1805
let attrs = self . infcx . tcx . get_attrs ( statik. def_id ) ;
1801
1806
let is_thread_local = attrs. iter ( ) . any ( |attr| attr. check_name ( "thread_local" ) ) ;
1802
1807
@@ -1813,47 +1818,45 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1813
1818
1814
1819
fn classify_drop_access_kind ( & self , place : & Place < ' tcx > ) -> StorageDeadOrDrop < ' tcx > {
1815
1820
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) ;
1845
1846
}
1846
1847
}
1847
- _ => base_access,
1848
1848
}
1849
+ _ => { } ,
1849
1850
}
1850
-
1851
- ProjectionElem :: ConstantIndex { .. }
1852
- | ProjectionElem :: Subslice { .. }
1853
- | ProjectionElem :: Index ( _) => base_access,
1854
1851
}
1852
+
1853
+ ProjectionElem :: ConstantIndex { .. }
1854
+ | ProjectionElem :: Subslice { .. }
1855
+ | ProjectionElem :: Index ( _) => { } ,
1855
1856
}
1857
+ base_ty = PlaceTy :: from ( base_ty) . projection_ty ( tcx, elem) . to_ty ( tcx) ;
1856
1858
}
1859
+ access
1857
1860
}
1858
1861
1859
1862
/// 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> {
1897
1900
"annotate_argument_and_return_for_borrow: reservation={:?}" ,
1898
1901
reservation
1899
1902
) ;
1903
+ let reservation = self . infcx . tcx . as_new_place ( reservation) ;
1900
1904
// 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,
1903
1907
_ => return None ,
1904
1908
} ;
1905
1909
0 commit comments