@@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId;
77use rustc_hir:: { AsyncGeneratorKind , GeneratorKind } ;
88use rustc_infer:: infer:: TyCtxtInferExt ;
99use rustc_infer:: traits:: ObligationCause ;
10+ use rustc_middle:: mir:: tcx:: PlaceTy ;
1011use rustc_middle:: mir:: {
1112 self , AggregateKind , BindingForm , BorrowKind , ClearCrossCrate , ConstraintCategory ,
1213 FakeReadCause , LocalDecl , LocalInfo , LocalKind , Location , Operand , Place , PlaceRef ,
@@ -22,6 +23,7 @@ use rustc_trait_selection::traits::TraitEngineExt as _;
2223use crate :: borrow_set:: TwoPhaseActivation ;
2324use crate :: borrowck_errors;
2425
26+ use crate :: diagnostics:: conflict_errors:: StorageDeadOrDrop :: LocalStorageDead ;
2527use crate :: diagnostics:: find_all_local_uses;
2628use crate :: {
2729 borrow_set:: BorrowData , diagnostics:: Instance , prefixes:: IsPrefixOf ,
@@ -1956,45 +1958,46 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
19561958
19571959 fn classify_drop_access_kind ( & self , place : PlaceRef < ' tcx > ) -> StorageDeadOrDrop < ' tcx > {
19581960 let tcx = self . infcx . tcx ;
1959- match place. last_projection ( ) {
1960- None => StorageDeadOrDrop :: LocalStorageDead ,
1961- Some ( ( place_base, elem) ) => {
1962- // FIXME(spastorino) make this iterate
1963- let base_access = self . classify_drop_access_kind ( place_base) ;
1964- match elem {
1965- ProjectionElem :: Deref => match base_access {
1966- StorageDeadOrDrop :: LocalStorageDead
1967- | StorageDeadOrDrop :: BoxedStorageDead => {
1968- assert ! (
1969- place_base. ty( self . body, tcx) . ty. is_box( ) ,
1970- "Drop of value behind a reference or raw pointer"
1971- ) ;
1972- StorageDeadOrDrop :: BoxedStorageDead
1973- }
1974- StorageDeadOrDrop :: Destructor ( _) => base_access,
1975- } ,
1976- ProjectionElem :: Field ( ..) | ProjectionElem :: Downcast ( ..) => {
1977- let base_ty = place_base. ty ( self . body , tcx) . ty ;
1978- match base_ty. kind ( ) {
1979- ty:: Adt ( def, _) if def. has_dtor ( tcx) => {
1980- // Report the outermost adt with a destructor
1981- match base_access {
1982- StorageDeadOrDrop :: Destructor ( _) => base_access,
1983- StorageDeadOrDrop :: LocalStorageDead
1984- | StorageDeadOrDrop :: BoxedStorageDead => {
1985- StorageDeadOrDrop :: Destructor ( base_ty)
1961+ let ( kind, _place_ty) = place. projection . iter ( ) . fold (
1962+ ( LocalStorageDead , PlaceTy :: from_ty ( self . body . local_decls [ place. local ] . ty ) ) ,
1963+ |( kind, place_ty) , & elem| {
1964+ (
1965+ match elem {
1966+ ProjectionElem :: Deref => match kind {
1967+ StorageDeadOrDrop :: LocalStorageDead
1968+ | StorageDeadOrDrop :: BoxedStorageDead => {
1969+ assert ! (
1970+ place_ty. ty. is_box( ) ,
1971+ "Drop of value behind a reference or raw pointer"
1972+ ) ;
1973+ StorageDeadOrDrop :: BoxedStorageDead
1974+ }
1975+ StorageDeadOrDrop :: Destructor ( _) => kind,
1976+ } ,
1977+ ProjectionElem :: Field ( ..) | ProjectionElem :: Downcast ( ..) => {
1978+ match place_ty. ty . kind ( ) {
1979+ ty:: Adt ( def, _) if def. has_dtor ( tcx) => {
1980+ // Report the outermost adt with a destructor
1981+ match kind {
1982+ StorageDeadOrDrop :: Destructor ( _) => kind,
1983+ StorageDeadOrDrop :: LocalStorageDead
1984+ | StorageDeadOrDrop :: BoxedStorageDead => {
1985+ StorageDeadOrDrop :: Destructor ( place_ty. ty )
1986+ }
19861987 }
19871988 }
1989+ _ => kind,
19881990 }
1989- _ => base_access,
19901991 }
1991- }
1992- ProjectionElem :: ConstantIndex { .. }
1993- | ProjectionElem :: Subslice { .. }
1994- | ProjectionElem :: Index ( _) => base_access,
1995- }
1996- }
1997- }
1992+ ProjectionElem :: ConstantIndex { .. }
1993+ | ProjectionElem :: Subslice { .. }
1994+ | ProjectionElem :: Index ( _) => kind,
1995+ } ,
1996+ place_ty. projection_ty ( tcx, elem) ,
1997+ )
1998+ } ,
1999+ ) ;
2000+ kind
19982001 }
19992002
20002003 /// Describe the reason for the fake borrow that was assigned to `place`.
0 commit comments