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:
bors 2022-04-24 12:58:16 +00:00
commit d8e59edbfa

View file

@ -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`.