Fix const drop checking
This commit is contained in:
parent
57fec79bec
commit
efe8ae730f
10 changed files with 57 additions and 67 deletions
|
@ -22,7 +22,7 @@ use std::mem;
|
|||
use std::ops::{ControlFlow, Deref};
|
||||
|
||||
use super::ops::{self, NonConstOp, Status};
|
||||
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop};
|
||||
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
|
||||
use super::resolver::FlowSensitiveAnalysis;
|
||||
use super::{ConstCx, Qualif};
|
||||
use crate::const_eval::is_unstable_const_fn;
|
||||
|
@ -35,7 +35,7 @@ type QualifResults<'mir, 'tcx, Q> =
|
|||
pub struct Qualifs<'mir, 'tcx> {
|
||||
has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
|
||||
needs_drop: Option<QualifResults<'mir, 'tcx, NeedsDrop>>,
|
||||
// needs_non_const_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
|
||||
needs_non_const_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
|
||||
|
@ -78,27 +78,25 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
|
|||
local: Local,
|
||||
location: Location,
|
||||
) -> bool {
|
||||
// FIXME(effects) replace with `NeedsNonconstDrop` after const traits work again
|
||||
/*
|
||||
let ty = ccx.body.local_decls[local].ty;
|
||||
if !NeedsDrop::in_any_value_of_ty(ccx, ty) {
|
||||
// Peeking into opaque types causes cycles if the current function declares said opaque
|
||||
// type. Thus we avoid short circuiting on the type and instead run the more expensive
|
||||
// analysis that looks at the actual usage within this function
|
||||
if !ty.has_opaque_types() && !NeedsNonConstDrop::in_any_value_of_ty(ccx, ty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let needs_non_const_drop = self.needs_non_const_drop.get_or_insert_with(|| {
|
||||
let ConstCx { tcx, body, .. } = *ccx;
|
||||
|
||||
FlowSensitiveAnalysis::new(NeedsDrop, ccx)
|
||||
.into_engine(tcx, &body)
|
||||
FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
|
||||
.into_engine(tcx, body)
|
||||
.iterate_to_fixpoint()
|
||||
.into_results_cursor(&body)
|
||||
.into_results_cursor(body)
|
||||
});
|
||||
|
||||
needs_non_const_drop.seek_before_primary_effect(location);
|
||||
needs_non_const_drop.get().contains(local)
|
||||
*/
|
||||
|
||||
self.needs_drop(ccx, local, location)
|
||||
}
|
||||
|
||||
/// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
|
||||
|
@ -1013,9 +1011,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
let mut err_span = self.span;
|
||||
let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty;
|
||||
|
||||
// FIXME(effects) replace with `NeedsNonConstDrop` once we fix const traits
|
||||
let ty_needs_non_const_drop =
|
||||
qualifs::NeedsDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place);
|
||||
qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place);
|
||||
|
||||
debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use rustc_span::{symbol::sym, 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
|
||||
|
@ -83,8 +83,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
|
|||
mir::TerminatorKind::Drop { place: dropped_place, .. } => {
|
||||
let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
|
||||
|
||||
// FIXME(effects) use `NeedsNonConstDrop`
|
||||
if !NeedsDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
|
||||
if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
|
||||
// Instead of throwing a bug, we just return here. This is because we have to
|
||||
// run custom `const Drop` impls.
|
||||
return;
|
||||
|
|
|
@ -23,8 +23,7 @@ pub fn in_any_value_of_ty<'tcx>(
|
|||
ConstQualifs {
|
||||
has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty),
|
||||
needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
|
||||
// FIXME(effects)
|
||||
needs_non_const_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
|
||||
needs_non_const_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty),
|
||||
custom_eq: CustomEq::in_any_value_of_ty(cx, ty),
|
||||
tainted_by_errors,
|
||||
}
|
||||
|
@ -155,12 +154,27 @@ impl Qualif for NeedsNonConstDrop {
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME(effects) constness
|
||||
// FIXME(effects): If `destruct` is not a `const_trait`,
|
||||
// or effects are disabled in this crate, then give up.
|
||||
let destruct_def_id = cx.tcx.require_lang_item(LangItem::Destruct, Some(cx.body.span));
|
||||
if cx.tcx.generics_of(destruct_def_id).host_effect_index.is_none()
|
||||
|| !cx.tcx.features().effects
|
||||
{
|
||||
return NeedsDrop::in_any_value_of_ty(cx, ty);
|
||||
}
|
||||
|
||||
let obligation = Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy_with_span(cx.body.span),
|
||||
cx.param_env,
|
||||
ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty]),
|
||||
ty::TraitRef::new(
|
||||
cx.tcx,
|
||||
destruct_def_id,
|
||||
[
|
||||
ty::GenericArg::from(ty),
|
||||
ty::GenericArg::from(cx.tcx.expected_const_effect_param_for_body(cx.def_id())),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue