Auto merge of #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))
This commit is contained in:
commit
d8e59edbfa
1 changed files with 38 additions and 35 deletions
|
@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
|
use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
|
use rustc_middle::mir::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
|
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
|
||||||
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
|
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
|
||||||
|
@ -22,6 +23,7 @@ use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||||
use crate::borrow_set::TwoPhaseActivation;
|
use crate::borrow_set::TwoPhaseActivation;
|
||||||
use crate::borrowck_errors;
|
use crate::borrowck_errors;
|
||||||
|
|
||||||
|
use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
|
||||||
use crate::diagnostics::find_all_local_uses;
|
use crate::diagnostics::find_all_local_uses;
|
||||||
use crate::{
|
use crate::{
|
||||||
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
||||||
|
@ -1956,45 +1958,46 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
fn classify_drop_access_kind(&self, place: PlaceRef<'tcx>) -> StorageDeadOrDrop<'tcx> {
|
fn classify_drop_access_kind(&self, place: PlaceRef<'tcx>) -> StorageDeadOrDrop<'tcx> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
match place.last_projection() {
|
let (kind, _place_ty) = place.projection.iter().fold(
|
||||||
None => StorageDeadOrDrop::LocalStorageDead,
|
(LocalStorageDead, PlaceTy::from_ty(self.body.local_decls[place.local].ty)),
|
||||||
Some((place_base, elem)) => {
|
|(kind, place_ty), &elem| {
|
||||||
// FIXME(spastorino) make this iterate
|
(
|
||||||
let base_access = self.classify_drop_access_kind(place_base);
|
match elem {
|
||||||
match elem {
|
ProjectionElem::Deref => match kind {
|
||||||
ProjectionElem::Deref => match base_access {
|
StorageDeadOrDrop::LocalStorageDead
|
||||||
StorageDeadOrDrop::LocalStorageDead
|
| StorageDeadOrDrop::BoxedStorageDead => {
|
||||||
| StorageDeadOrDrop::BoxedStorageDead => {
|
assert!(
|
||||||
assert!(
|
place_ty.ty.is_box(),
|
||||||
place_base.ty(self.body, tcx).ty.is_box(),
|
"Drop of value behind a reference or raw pointer"
|
||||||
"Drop of value behind a reference or raw pointer"
|
);
|
||||||
);
|
StorageDeadOrDrop::BoxedStorageDead
|
||||||
StorageDeadOrDrop::BoxedStorageDead
|
}
|
||||||
}
|
StorageDeadOrDrop::Destructor(_) => kind,
|
||||||
StorageDeadOrDrop::Destructor(_) => base_access,
|
},
|
||||||
},
|
ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
|
||||||
ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
|
match place_ty.ty.kind() {
|
||||||
let base_ty = place_base.ty(self.body, tcx).ty;
|
ty::Adt(def, _) if def.has_dtor(tcx) => {
|
||||||
match base_ty.kind() {
|
// Report the outermost adt with a destructor
|
||||||
ty::Adt(def, _) if def.has_dtor(tcx) => {
|
match kind {
|
||||||
// Report the outermost adt with a destructor
|
StorageDeadOrDrop::Destructor(_) => kind,
|
||||||
match base_access {
|
StorageDeadOrDrop::LocalStorageDead
|
||||||
StorageDeadOrDrop::Destructor(_) => base_access,
|
| StorageDeadOrDrop::BoxedStorageDead => {
|
||||||
StorageDeadOrDrop::LocalStorageDead
|
StorageDeadOrDrop::Destructor(place_ty.ty)
|
||||||
| StorageDeadOrDrop::BoxedStorageDead => {
|
}
|
||||||
StorageDeadOrDrop::Destructor(base_ty)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => kind,
|
||||||
}
|
}
|
||||||
_ => base_access,
|
|
||||||
}
|
}
|
||||||
}
|
ProjectionElem::ConstantIndex { .. }
|
||||||
ProjectionElem::ConstantIndex { .. }
|
| ProjectionElem::Subslice { .. }
|
||||||
| ProjectionElem::Subslice { .. }
|
| ProjectionElem::Index(_) => kind,
|
||||||
| ProjectionElem::Index(_) => base_access,
|
},
|
||||||
}
|
place_ty.projection_ty(tcx, elem),
|
||||||
}
|
)
|
||||||
}
|
},
|
||||||
|
);
|
||||||
|
kind
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describe the reason for the fake borrow that was assigned to `place`.
|
/// Describe the reason for the fake borrow that was assigned to `place`.
|
||||||
|
|
Loading…
Add table
Reference in a new issue