Skip to content

Commit d8e59ed

Browse files
committed
Auto merge of rust-lang#96359 - SparrowLii:drop_kind, r=oli-obk
make `classify_drop_access_kind` iterate This PR: 1. fixes the FIXME of `classify_drop_access_kind` func in the borrowck part. The process of obtaining `StorageDeadOrDrop` has been changed from recursive to iterative. 2. gets `place_ty` in each iteration, avoid repeatedly getting the `ty` of the same place (O(n^2) => O(n))
2 parents b759b22 + a34e1b5 commit d8e59ed

File tree

1 file changed

+38
-35
lines changed

1 file changed

+38
-35
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+38-35
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId;
77
use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
88
use rustc_infer::infer::TyCtxtInferExt;
99
use rustc_infer::traits::ObligationCause;
10+
use rustc_middle::mir::tcx::PlaceTy;
1011
use 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 _;
2223
use crate::borrow_set::TwoPhaseActivation;
2324
use crate::borrowck_errors;
2425

26+
use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
2527
use crate::diagnostics::find_all_local_uses;
2628
use 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

Comments
 (0)