Const dropping
This commit is contained in:
parent
d9797d23d5
commit
104e40fb74
9 changed files with 141 additions and 28 deletions
|
@ -22,7 +22,7 @@ use std::mem;
|
|||
use std::ops::Deref;
|
||||
|
||||
use super::ops::{self, NonConstOp, Status};
|
||||
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop};
|
||||
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsNonConstDrop};
|
||||
use super::resolver::FlowSensitiveAnalysis;
|
||||
use super::{is_lang_panic_fn, ConstCx, Qualif};
|
||||
use crate::const_eval::is_unstable_const_fn;
|
||||
|
@ -39,7 +39,7 @@ type QualifResults<'mir, 'tcx, Q> =
|
|||
#[derive(Default)]
|
||||
pub struct Qualifs<'mir, 'tcx> {
|
||||
has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
|
||||
needs_drop: Option<QualifResults<'mir, 'tcx, NeedsDrop>>,
|
||||
needs_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
|
||||
indirectly_mutable: Option<IndirectlyMutableResults<'mir, 'tcx>>,
|
||||
}
|
||||
|
||||
|
@ -80,14 +80,14 @@ impl Qualifs<'mir, 'tcx> {
|
|||
location: Location,
|
||||
) -> bool {
|
||||
let ty = ccx.body.local_decls[local].ty;
|
||||
if !NeedsDrop::in_any_value_of_ty(ccx, ty) {
|
||||
if !NeedsNonConstDrop::in_any_value_of_ty(ccx, ty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let needs_drop = self.needs_drop.get_or_insert_with(|| {
|
||||
let ConstCx { tcx, body, .. } = *ccx;
|
||||
|
||||
FlowSensitiveAnalysis::new(NeedsDrop, ccx)
|
||||
FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
|
||||
.into_engine(tcx, &body)
|
||||
.iterate_to_fixpoint()
|
||||
.into_results_cursor(&body)
|
||||
|
@ -991,7 +991,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
|
|||
// Check to see if the type of this place can ever have a drop impl. If not, this
|
||||
// `Drop` terminator is frivolous.
|
||||
let ty_needs_drop =
|
||||
dropped_place.ty(self.body, self.tcx).ty.needs_drop(self.tcx, self.param_env);
|
||||
dropped_place.ty(self.body, self.tcx).ty.needs_non_const_drop(self.tcx, self.param_env);
|
||||
|
||||
if !ty_needs_drop {
|
||||
return;
|
||||
|
|
|
@ -5,7 +5,7 @@ use rustc_span::Span;
|
|||
|
||||
use super::check::Qualifs;
|
||||
use super::ops::{self, NonConstOp};
|
||||
use super::qualifs::{NeedsDrop, Qualif};
|
||||
use super::qualifs::{NeedsNonConstDrop, Qualif};
|
||||
use super::ConstCx;
|
||||
|
||||
/// Returns `true` if we should use the more precise live drop checker that runs after drop
|
||||
|
@ -78,7 +78,7 @@ impl Visitor<'tcx> for CheckLiveDrops<'mir, 'tcx> {
|
|||
match &terminator.kind {
|
||||
mir::TerminatorKind::Drop { place: dropped_place, .. } => {
|
||||
let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
|
||||
if !NeedsDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
|
||||
if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
|
||||
bug!(
|
||||
"Drop elaboration left behind a Drop for a type that does not need dropping"
|
||||
);
|
||||
|
|
|
@ -17,7 +17,7 @@ pub fn in_any_value_of_ty(
|
|||
) -> ConstQualifs {
|
||||
ConstQualifs {
|
||||
has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty),
|
||||
needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
|
||||
needs_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty),
|
||||
custom_eq: CustomEq::in_any_value_of_ty(cx, ty),
|
||||
error_occured,
|
||||
}
|
||||
|
@ -97,10 +97,10 @@ impl Qualif for HasMutInterior {
|
|||
/// This must be ruled out (a) because we cannot run `Drop` during compile-time
|
||||
/// as that might not be a `const fn`, and (b) because implicit promotion would
|
||||
/// remove side-effects that occur as part of dropping that value.
|
||||
pub struct NeedsDrop;
|
||||
pub struct NeedsNonConstDrop;
|
||||
|
||||
impl Qualif for NeedsDrop {
|
||||
const ANALYSIS_NAME: &'static str = "flow_needs_drop";
|
||||
impl Qualif for NeedsNonConstDrop {
|
||||
const ANALYSIS_NAME: &'static str = "flow_needs_nonconst_drop";
|
||||
const IS_CLEARED_ON_MOVE: bool = true;
|
||||
|
||||
fn in_qualifs(qualifs: &ConstQualifs) -> bool {
|
||||
|
@ -112,7 +112,7 @@ impl Qualif for NeedsDrop {
|
|||
}
|
||||
|
||||
fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
|
||||
adt.has_dtor(cx.tcx)
|
||||
adt.has_non_const_dtor(cx.tcx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue