@@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId;
7
7
use rustc_hir:: { AsyncGeneratorKind , GeneratorKind } ;
8
8
use rustc_infer:: infer:: TyCtxtInferExt ;
9
9
use rustc_infer:: traits:: ObligationCause ;
10
+ use rustc_middle:: mir:: tcx:: PlaceTy ;
10
11
use rustc_middle:: mir:: {
11
12
self , AggregateKind , BindingForm , BorrowKind , ClearCrossCrate , ConstraintCategory ,
12
13
FakeReadCause , LocalDecl , LocalInfo , LocalKind , Location , Operand , Place , PlaceRef ,
@@ -22,6 +23,7 @@ use rustc_trait_selection::traits::TraitEngineExt as _;
22
23
use crate :: borrow_set:: TwoPhaseActivation ;
23
24
use crate :: borrowck_errors;
24
25
26
+ use crate :: diagnostics:: conflict_errors:: StorageDeadOrDrop :: LocalStorageDead ;
25
27
use crate :: diagnostics:: find_all_local_uses;
26
28
use crate :: {
27
29
borrow_set:: BorrowData , diagnostics:: Instance , prefixes:: IsPrefixOf ,
@@ -1956,45 +1958,46 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1956
1958
1957
1959
fn classify_drop_access_kind ( & self , place : PlaceRef < ' tcx > ) -> StorageDeadOrDrop < ' tcx > {
1958
1960
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
+ }
1986
1987
}
1987
1988
}
1989
+ _ => kind,
1988
1990
}
1989
- _ => base_access,
1990
1991
}
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
1998
2001
}
1999
2002
2000
2003
/// Describe the reason for the fake borrow that was assigned to `place`.
0 commit comments