Rename ~const Drop
to ~const Destruct
This commit is contained in:
parent
4df2a28aee
commit
1f3ee7f32e
32 changed files with 296 additions and 192 deletions
|
@ -1569,7 +1569,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
super::ImplSource::AutoImpl(..)
|
||||
| super::ImplSource::Builtin(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::ConstDrop(_) => {
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
// These traits have no associated types.
|
||||
selcx.tcx().sess.delay_span_bug(
|
||||
obligation.cause.span,
|
||||
|
@ -1644,7 +1644,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
|
|||
| super::ImplSource::Builtin(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::TraitAlias(..)
|
||||
| super::ImplSource::ConstDrop(_) => {
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
// we don't create Select candidates with this kind of resolution
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//! candidates. See the [rustc dev guide] for more details.
|
||||
//!
|
||||
//! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
|
||||
use hir::LangItem;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
|
@ -307,7 +308,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
} else if lang_items.drop_trait() == Some(def_id)
|
||||
&& obligation.predicate.is_const_if_const()
|
||||
{
|
||||
self.assemble_const_drop_candidates(obligation, &mut candidates);
|
||||
// holds to make it easier to transition
|
||||
// FIXME(fee1-dead): add a note for selection error of `~const Drop`
|
||||
// when beta is bumped
|
||||
// FIXME: remove this when beta is bumped
|
||||
#[cfg(bootstrap)]
|
||||
{}
|
||||
|
||||
candidates.vec.push(SelectionCandidate::ConstDestructCandidate(None))
|
||||
} else if lang_items.destruct_trait() == Some(def_id) {
|
||||
self.assemble_const_destruct_candidates(obligation, &mut candidates);
|
||||
} else {
|
||||
if lang_items.clone_trait() == Some(def_id) {
|
||||
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
|
||||
|
@ -906,15 +916,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn assemble_const_drop_candidates(
|
||||
fn assemble_const_destruct_candidates(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||
) {
|
||||
// If the predicate is `~const Drop` in a non-const environment, we don't actually need
|
||||
// If the predicate is `~const Destruct` in a non-const environment, we don't actually need
|
||||
// to check anything. We'll short-circuit checking any obligations in confirmation, too.
|
||||
if obligation.param_env.constness() == hir::Constness::NotConst {
|
||||
candidates.vec.push(ConstDropCandidate(None));
|
||||
if !obligation.is_const() {
|
||||
candidates.vec.push(ConstDestructCandidate(None));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -927,7 +937,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Param(_)
|
||||
| ty::Placeholder(_)
|
||||
| ty::Projection(_) => {
|
||||
// We don't know if these are `~const Drop`, at least
|
||||
// We don't know if these are `~const Destruct`, at least
|
||||
// not structurally... so don't push a candidate.
|
||||
}
|
||||
|
||||
|
@ -951,14 +961,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Generator(..)
|
||||
| ty::Tuple(_)
|
||||
| ty::GeneratorWitness(_) => {
|
||||
// These are built-in, and cannot have a custom `impl const Drop`.
|
||||
candidates.vec.push(ConstDropCandidate(None));
|
||||
// These are built-in, and cannot have a custom `impl const Destruct`.
|
||||
candidates.vec.push(ConstDestructCandidate(None));
|
||||
}
|
||||
|
||||
ty::Adt(..) => {
|
||||
// Find a custom `impl Drop` impl, if it exists
|
||||
let relevant_impl = self.tcx().find_map_relevant_impl(
|
||||
obligation.predicate.def_id(),
|
||||
self.tcx().require_lang_item(LangItem::Drop, None),
|
||||
obligation.predicate.skip_binder().trait_ref.self_ty(),
|
||||
Some,
|
||||
);
|
||||
|
@ -966,11 +976,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
if let Some(impl_def_id) = relevant_impl {
|
||||
// Check that `impl Drop` is actually const, if there is a custom impl
|
||||
if self.tcx().impl_constness(impl_def_id) == hir::Constness::Const {
|
||||
candidates.vec.push(ConstDropCandidate(Some(impl_def_id)));
|
||||
candidates.vec.push(ConstDestructCandidate(Some(impl_def_id)));
|
||||
}
|
||||
} else {
|
||||
// Otherwise check the ADT like a built-in type (structurally)
|
||||
candidates.vec.push(ConstDropCandidate(None));
|
||||
candidates.vec.push(ConstDestructCandidate(None));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::Constness;
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||
|
@ -29,9 +28,9 @@ use crate::traits::TraitNotObjectSafe;
|
|||
use crate::traits::VtblSegment;
|
||||
use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
|
||||
use crate::traits::{
|
||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, ImplSourceConstDropData,
|
||||
ImplSourceDiscriminantKindData, ImplSourceFnPointerData, ImplSourceGeneratorData,
|
||||
ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData,
|
||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||
ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData,
|
||||
};
|
||||
use crate::traits::{ObjectCastObligation, PredicateObligation, TraitObligation};
|
||||
|
@ -156,9 +155,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
Ok(ImplSource::TraitUpcasting(data))
|
||||
}
|
||||
|
||||
ConstDropCandidate(def_id) => {
|
||||
let data = self.confirm_const_drop_candidate(obligation, def_id)?;
|
||||
Ok(ImplSource::ConstDrop(data))
|
||||
ConstDestructCandidate(def_id) => {
|
||||
let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
|
||||
Ok(ImplSource::ConstDestruct(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1037,14 +1036,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
Ok(ImplSourceBuiltinData { nested })
|
||||
}
|
||||
|
||||
fn confirm_const_drop_candidate(
|
||||
fn confirm_const_destruct_candidate(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
impl_def_id: Option<DefId>,
|
||||
) -> Result<ImplSourceConstDropData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
// `~const Drop` in a non-const environment is always trivially true, since our type is `Drop`
|
||||
if obligation.param_env.constness() == Constness::NotConst {
|
||||
return Ok(ImplSourceConstDropData { nested: vec![] });
|
||||
) -> Result<ImplSourceConstDestructData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||
// `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
|
||||
if !obligation.is_const() {
|
||||
return Ok(ImplSourceConstDestructData { nested: vec![] });
|
||||
}
|
||||
|
||||
let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None);
|
||||
// FIXME: remove if statement below when beta is bumped
|
||||
#[cfg(bootstrap)]
|
||||
{}
|
||||
|
||||
if obligation.predicate.skip_binder().def_id() == drop_trait
|
||||
{
|
||||
return Ok(ImplSourceConstDestructData { nested: vec![] });
|
||||
}
|
||||
|
||||
let tcx = self.tcx();
|
||||
|
@ -1054,9 +1063,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||
|
||||
// If we have a custom `impl const Drop`, then
|
||||
// first check it like a regular impl candidate
|
||||
// first check it like a regular impl candidate.
|
||||
// This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand.
|
||||
if let Some(impl_def_id) = impl_def_id {
|
||||
nested.extend(self.confirm_impl_candidate(obligation, impl_def_id).nested);
|
||||
let obligations = self.infcx.commit_unconditionally(|_| {
|
||||
let mut new_obligation = obligation.clone();
|
||||
new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| { trait_pred.trait_ref.def_id = drop_trait; trait_pred });
|
||||
let substs = self.rematch_impl(impl_def_id, &new_obligation);
|
||||
debug!(?substs, "impl substs");
|
||||
let cause = obligation.derived_cause(ImplDerivedObligation);
|
||||
ensure_sufficient_stack(|| {
|
||||
self.vtable_impl(
|
||||
impl_def_id,
|
||||
substs,
|
||||
cause,
|
||||
new_obligation.recursion_depth + 1,
|
||||
new_obligation.param_env,
|
||||
)
|
||||
})
|
||||
});
|
||||
nested.extend(obligations.nested);
|
||||
}
|
||||
|
||||
// We want to confirm the ADT's fields if we have an ADT
|
||||
|
@ -1114,7 +1140,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
self_ty
|
||||
.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Drop, None),
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
|
@ -1140,7 +1166,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let predicate = self_ty
|
||||
.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Drop, None),
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
|
@ -1158,6 +1184,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(ImplSourceConstDropData { nested })
|
||||
Ok(ImplSourceConstDestructData { nested })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1179,7 +1179,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
GeneratorCandidate => {}
|
||||
// FnDef where the function is const
|
||||
FnPointerCandidate { is_const: true } => {}
|
||||
ConstDropCandidate(_) => {}
|
||||
ConstDestructCandidate(_) => {}
|
||||
_ => {
|
||||
// reject all other types of candidates
|
||||
continue;
|
||||
|
@ -1589,7 +1589,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
};
|
||||
|
||||
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
|
||||
// `DiscriminantKindCandidate`, and `ConstDropCandidate` to anything else.
|
||||
// `DiscriminantKindCandidate`, and `ConstDestructCandidate` to anything else.
|
||||
//
|
||||
// This is a fix for #53123 and prevents winnowing from accidentally extending the
|
||||
// lifetime of a variable.
|
||||
|
@ -1606,7 +1606,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
BuiltinCandidate { has_nested: false }
|
||||
| DiscriminantKindCandidate
|
||||
| PointeeCandidate
|
||||
| ConstDropCandidate(_),
|
||||
| ConstDestructCandidate(_),
|
||||
_,
|
||||
) => true,
|
||||
(
|
||||
|
@ -1614,7 +1614,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
BuiltinCandidate { has_nested: false }
|
||||
| DiscriminantKindCandidate
|
||||
| PointeeCandidate
|
||||
| ConstDropCandidate(_),
|
||||
| ConstDestructCandidate(_),
|
||||
) => false,
|
||||
|
||||
(ParamCandidate(other), ParamCandidate(victim)) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue