Rename ~const Drop
to ~const Destruct
This commit is contained in:
parent
4df2a28aee
commit
1f3ee7f32e
32 changed files with 296 additions and 192 deletions
|
@ -3,6 +3,7 @@
|
|||
//! See the `Qualif` trait for more info.
|
||||
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_middle::mir::*;
|
||||
|
@ -152,18 +153,14 @@ impl Qualif for NeedsNonConstDrop {
|
|||
return false;
|
||||
}
|
||||
|
||||
let Some(drop_trait) = cx.tcx.lang_items().drop_trait() else {
|
||||
// there is no way to define a type that needs non-const drop
|
||||
// without having the lang item present.
|
||||
return false;
|
||||
};
|
||||
let destruct = cx.tcx.require_lang_item(LangItem::Destruct, None);
|
||||
|
||||
let obligation = Obligation::new(
|
||||
ObligationCause::dummy(),
|
||||
cx.param_env,
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: drop_trait,
|
||||
def_id: destruct,
|
||||
substs: cx.tcx.mk_substs_trait(ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
|
@ -174,15 +171,16 @@ impl Qualif for NeedsNonConstDrop {
|
|||
cx.tcx.infer_ctxt().enter(|infcx| {
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
|
||||
// If we couldn't select a const drop candidate, then it's bad
|
||||
// If we couldn't select a const destruct candidate, then it's bad
|
||||
return true;
|
||||
};
|
||||
|
||||
if !matches!(
|
||||
impl_src,
|
||||
ImplSource::ConstDrop(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
|
||||
ImplSource::ConstDestruct(_)
|
||||
| ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
|
||||
) {
|
||||
// If our const drop candidate is not ConstDrop or implied by the param env,
|
||||
// If our const destruct candidate is not ConstDestruct or implied by the param env,
|
||||
// then it's bad
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ language_item_table! {
|
|||
Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
|
||||
Destructible, sym::destructible, destructible_trait, Target::Trait, GenericRequirement::None;
|
||||
Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None;
|
||||
|
||||
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||
|
|
|
@ -93,10 +93,6 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
|||
let Trait(trait_predicate) = predicate.kind().skip_binder() else {
|
||||
continue
|
||||
};
|
||||
if trait_predicate.is_const_if_const() {
|
||||
// `~const Drop` definitely have meanings so avoid linting here.
|
||||
continue;
|
||||
}
|
||||
let def_id = trait_predicate.trait_ref.def_id;
|
||||
if cx.tcx.lang_items().drop_trait() == Some(def_id) {
|
||||
// Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern.
|
||||
|
|
|
@ -577,7 +577,7 @@ pub enum ImplSource<'tcx, N> {
|
|||
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
|
||||
|
||||
/// ImplSource for a `const Drop` implementation.
|
||||
ConstDrop(ImplSourceConstDropData<N>),
|
||||
ConstDestruct(ImplSourceConstDestructData<N>),
|
||||
}
|
||||
|
||||
impl<'tcx, N> ImplSource<'tcx, N> {
|
||||
|
@ -595,7 +595,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||
| ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(),
|
||||
ImplSource::TraitAlias(d) => d.nested,
|
||||
ImplSource::TraitUpcasting(d) => d.nested,
|
||||
ImplSource::ConstDrop(i) => i.nested,
|
||||
ImplSource::ConstDestruct(i) => i.nested,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -613,7 +613,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||
| ImplSource::Pointee(ImplSourcePointeeData) => &[],
|
||||
ImplSource::TraitAlias(d) => &d.nested,
|
||||
ImplSource::TraitUpcasting(d) => &d.nested,
|
||||
ImplSource::ConstDrop(i) => &i.nested,
|
||||
ImplSource::ConstDestruct(i) => &i.nested,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -672,9 +672,11 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||
nested: d.nested.into_iter().map(f).collect(),
|
||||
})
|
||||
}
|
||||
ImplSource::ConstDrop(i) => ImplSource::ConstDrop(ImplSourceConstDropData {
|
||||
nested: i.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
ImplSource::ConstDestruct(i) => {
|
||||
ImplSource::ConstDestruct(ImplSourceConstDestructData {
|
||||
nested: i.nested.into_iter().map(f).collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -767,7 +769,7 @@ pub struct ImplSourceDiscriminantKindData;
|
|||
pub struct ImplSourcePointeeData;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
|
||||
pub struct ImplSourceConstDropData<N> {
|
||||
pub struct ImplSourceConstDestructData<N> {
|
||||
pub nested: Vec<N>,
|
||||
}
|
||||
|
||||
|
|
|
@ -146,8 +146,8 @@ pub enum SelectionCandidate<'tcx> {
|
|||
|
||||
BuiltinUnsizeCandidate,
|
||||
|
||||
/// Implementation of `const Drop`, optionally from a custom `impl const Drop`.
|
||||
ConstDropCandidate(Option<DefId>),
|
||||
/// Implementation of `const Destruct`, optionally from a custom `impl const Drop`.
|
||||
ConstDestructCandidate(Option<DefId>),
|
||||
}
|
||||
|
||||
/// The result of trait evaluation. The order is important
|
||||
|
|
|
@ -33,7 +33,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
|
|||
|
||||
super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
|
||||
|
||||
super::ImplSource::ConstDrop(ref d) => write!(f, "{:?}", d),
|
||||
super::ImplSource::ConstDestruct(ref d) => write!(f, "{:?}", d),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,9 +120,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx,
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDropData<N> {
|
||||
impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDestructData<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ImplSourceConstDropData(nested={:?})", self.nested)
|
||||
write!(f, "ImplSourceConstDestructData(nested={:?})", self.nested)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -765,6 +765,7 @@ impl<'tcx> TraitPredicate<'tcx> {
|
|||
if unlikely!(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) {
|
||||
// remap without changing constness of this predicate.
|
||||
// this is because `T: ~const Drop` has a different meaning to `T: Drop`
|
||||
// FIXME(fee1-dead): remove this logic after beta bump
|
||||
param_env.remap_constness_with(self.constness)
|
||||
} else {
|
||||
*param_env = param_env.with_constness(self.constness.and(param_env.constness()))
|
||||
|
|
|
@ -571,7 +571,7 @@ symbols! {
|
|||
deref_target,
|
||||
derive,
|
||||
derive_default_enum,
|
||||
destructible,
|
||||
destruct,
|
||||
destructuring_assignment,
|
||||
diagnostic,
|
||||
direct,
|
||||
|
|
|
@ -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)) => {
|
||||
|
|
|
@ -378,7 +378,7 @@ fn resolve_associated_item<'tcx>(
|
|||
| traits::ImplSource::DiscriminantKind(..)
|
||||
| traits::ImplSource::Pointee(..)
|
||||
| traits::ImplSource::TraitUpcasting(_)
|
||||
| traits::ImplSource::ConstDrop(_) => None,
|
||||
| traits::ImplSource::ConstDestruct(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ use core::ptr::{self, NonNull};
|
|||
#[doc(inline)]
|
||||
pub use core::alloc::*;
|
||||
|
||||
use core::marker::Destruct;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
|
@ -324,12 +326,16 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
|
|||
#[cfg_attr(not(test), lang = "box_free")]
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
// This signature has to be the same as `Box`, otherwise an ICE will happen.
|
||||
// When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
|
||||
// well.
|
||||
// For example if `Box` is changed to `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
|
||||
// this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well.
|
||||
pub(crate) const unsafe fn box_free<T: ?Sized, A: ~const Allocator + ~const Drop>(
|
||||
pub(crate) const unsafe fn box_free<
|
||||
T: ?Sized,
|
||||
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||
>(
|
||||
ptr: Unique<T>,
|
||||
alloc: A,
|
||||
) {
|
||||
|
|
|
@ -331,6 +331,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
|
||||
where
|
||||
B::Owned: ~const Borrow<B>,
|
||||
|
|
|
@ -143,7 +143,7 @@ use core::hash::{Hash, Hasher};
|
|||
#[cfg(not(no_global_oom_handling))]
|
||||
use core::iter::FromIterator;
|
||||
use core::iter::{FusedIterator, Iterator};
|
||||
use core::marker::{Unpin, Unsize};
|
||||
use core::marker::{Destruct, Unpin, Unsize};
|
||||
use core::mem;
|
||||
use core::ops::{
|
||||
CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver,
|
||||
|
@ -349,9 +349,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn new_in(x: T, alloc: A) -> Self
|
||||
where
|
||||
A: ~const Allocator + ~const Drop,
|
||||
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||
{
|
||||
let mut boxed = Self::new_uninit_in(alloc);
|
||||
unsafe {
|
||||
|
@ -378,10 +379,11 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||
#[inline]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
|
||||
where
|
||||
T: ~const Drop,
|
||||
A: ~const Allocator + ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||
{
|
||||
let mut boxed = Self::try_new_uninit_in(alloc)?;
|
||||
unsafe {
|
||||
|
@ -415,9 +417,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[cfg(not(no_global_oom_handling))]
|
||||
#[must_use]
|
||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
|
||||
where
|
||||
A: ~const Allocator + ~const Drop,
|
||||
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||
{
|
||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
|
||||
|
@ -453,9 +456,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
|
||||
where
|
||||
A: ~const Allocator + ~const Drop,
|
||||
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||
{
|
||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||
let ptr = alloc.allocate(layout)?.cast();
|
||||
|
@ -487,9 +491,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[cfg(not(no_global_oom_handling))]
|
||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||
#[must_use]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
|
||||
where
|
||||
A: ~const Allocator + ~const Drop,
|
||||
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||
{
|
||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
|
||||
|
@ -525,9 +530,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
|
||||
where
|
||||
A: ~const Allocator + ~const Drop,
|
||||
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||
{
|
||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||
let ptr = alloc.allocate_zeroed(layout)?.cast();
|
||||
|
@ -541,9 +547,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
|
||||
where
|
||||
A: 'static + ~const Allocator + ~const Drop,
|
||||
A: 'static + ~const Allocator + ~const Drop + ~const Destruct,
|
||||
{
|
||||
Self::into_pin(Self::new_in(x, alloc))
|
||||
}
|
||||
|
@ -572,9 +579,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||
#[unstable(feature = "box_into_inner", issue = "80437")]
|
||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||
#[inline]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn into_inner(boxed: Self) -> T
|
||||
where
|
||||
Self: ~const Drop,
|
||||
Self: ~const Drop + ~const Destruct,
|
||||
{
|
||||
*boxed
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! impl bool {}
|
||||
|
||||
use crate::marker::Destruct;
|
||||
|
||||
#[lang = "bool"]
|
||||
impl bool {
|
||||
/// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html),
|
||||
|
@ -16,9 +18,10 @@ impl bool {
|
|||
#[unstable(feature = "bool_to_option", issue = "80967")]
|
||||
#[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
|
||||
#[inline]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn then_some<T>(self, t: T) -> Option<T>
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
{
|
||||
if self { Some(t) } else { None }
|
||||
}
|
||||
|
@ -35,10 +38,11 @@ impl bool {
|
|||
#[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
|
||||
#[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
|
||||
#[inline]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn then<T, F>(self, f: F) -> Option<T>
|
||||
where
|
||||
F: ~const FnOnce() -> T,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
if self { Some(f()) } else { None }
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::marker::Destruct;
|
||||
|
||||
/// A common trait for the ability to explicitly duplicate an object.
|
||||
///
|
||||
/// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while
|
||||
|
@ -128,9 +130,10 @@ pub trait Clone: Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[default_method_body_is_const]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
fn clone_from(&mut self, source: &Self)
|
||||
where
|
||||
Self: ~const Drop,
|
||||
Self: ~const Drop + ~const Destruct,
|
||||
{
|
||||
*self = source.clone()
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
)]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::marker::DiscriminantKind;
|
||||
use crate::marker::{Destruct, DiscriminantKind};
|
||||
use crate::mem;
|
||||
|
||||
// These imports are used for simplifying intra-doc links
|
||||
|
@ -2353,6 +2353,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
|||
#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
|
||||
#[lang = "const_eval_select"]
|
||||
#[rustc_do_not_const_check]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const unsafe fn const_eval_select<ARG, F, G, RET>(
|
||||
arg: ARG,
|
||||
_called_in_const: F,
|
||||
|
@ -2360,7 +2361,7 @@ pub const unsafe fn const_eval_select<ARG, F, G, RET>(
|
|||
) -> RET
|
||||
where
|
||||
F: ~const FnOnce<ARG, Output = RET>,
|
||||
G: FnOnce<ARG, Output = RET> + ~const Drop,
|
||||
G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
|
||||
{
|
||||
called_at_rt.call_once(arg)
|
||||
}
|
||||
|
@ -2372,6 +2373,7 @@ where
|
|||
)]
|
||||
#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
|
||||
#[lang = "const_eval_select_ct"]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const unsafe fn const_eval_select_ct<ARG, F, G, RET>(
|
||||
arg: ARG,
|
||||
called_in_const: F,
|
||||
|
@ -2379,7 +2381,7 @@ pub const unsafe fn const_eval_select_ct<ARG, F, G, RET>(
|
|||
) -> RET
|
||||
where
|
||||
F: ~const FnOnce<ARG, Output = RET>,
|
||||
G: FnOnce<ARG, Output = RET> + ~const Drop,
|
||||
G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
|
||||
{
|
||||
called_in_const.call_once(arg)
|
||||
}
|
||||
|
|
|
@ -794,10 +794,19 @@ impl<T: ?Sized> Unpin for *mut T {}
|
|||
|
||||
/// A marker for types that can be dropped.
|
||||
///
|
||||
/// The compiler logic for this trait is currently unimplemented.
|
||||
/// This should be used for `~const` bounds,
|
||||
/// as non-const bounds will always hold for every type.
|
||||
#[unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[cfg_attr(not(bootstrap), lang = "destructible")]
|
||||
pub trait Destructible {}
|
||||
#[cfg_attr(not(bootstrap), lang = "destruct")]
|
||||
#[cfg_attr(
|
||||
not(bootstrap),
|
||||
rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg,)
|
||||
)]
|
||||
pub trait Destruct {}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
impl<T: ?Sized> const Destruct for T {}
|
||||
|
||||
/// Implementations of `Copy` for primitive types.
|
||||
///
|
||||
|
|
|
@ -503,6 +503,7 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
|
||||
use crate::marker::Destruct;
|
||||
use crate::panicking::{panic, panic_str};
|
||||
use crate::pin::Pin;
|
||||
use crate::{
|
||||
|
@ -772,9 +773,10 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn unwrap_or(self, default: T) -> T
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(x) => x,
|
||||
|
@ -794,10 +796,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn unwrap_or_else<F>(self, f: F) -> T
|
||||
where
|
||||
F: ~const FnOnce() -> T,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(x) => x,
|
||||
|
@ -899,10 +902,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn map<U, F>(self, f: F) -> Option<U>
|
||||
where
|
||||
F: ~const FnOnce(T) -> U,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(x) => Some(f(x)),
|
||||
|
@ -928,10 +932,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[unstable(feature = "result_option_inspect", issue = "91345")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn inspect<F>(self, f: F) -> Self
|
||||
where
|
||||
F: ~const FnOnce(&T),
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
if let Some(ref x) = self {
|
||||
f(x);
|
||||
|
@ -961,11 +966,12 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn map_or<U, F>(self, default: U, f: F) -> U
|
||||
where
|
||||
F: ~const FnOnce(T) -> U,
|
||||
F: ~const Drop,
|
||||
U: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
U: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(t) => f(t),
|
||||
|
@ -990,12 +996,13 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U
|
||||
where
|
||||
D: ~const FnOnce() -> U,
|
||||
D: ~const Drop,
|
||||
D: ~const Drop + ~const Destruct,
|
||||
F: ~const FnOnce(T) -> U,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(t) => f(t),
|
||||
|
@ -1027,9 +1034,10 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn ok_or<E>(self, err: E) -> Result<T, E>
|
||||
where
|
||||
E: ~const Drop,
|
||||
E: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(v) => Ok(v),
|
||||
|
@ -1056,10 +1064,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
|
||||
where
|
||||
F: ~const FnOnce() -> E,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(v) => Ok(v),
|
||||
|
@ -1190,10 +1199,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn and<U>(self, optb: Option<U>) -> Option<U>
|
||||
where
|
||||
T: ~const Drop,
|
||||
U: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
U: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(_) => optb,
|
||||
|
@ -1232,10 +1242,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn and_then<U, F>(self, f: F) -> Option<U>
|
||||
where
|
||||
F: ~const FnOnce(T) -> Option<U>,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(x) => f(x),
|
||||
|
@ -1270,11 +1281,12 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "option_filter", since = "1.27.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn filter<P>(self, predicate: P) -> Self
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
P: ~const FnOnce(&T) -> bool,
|
||||
P: ~const Drop,
|
||||
P: ~const Drop + ~const Destruct,
|
||||
{
|
||||
if let Some(x) = self {
|
||||
if predicate(&x) {
|
||||
|
@ -1314,9 +1326,10 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn or(self, optb: Option<T>) -> Option<T>
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(x) => Some(x),
|
||||
|
@ -1340,10 +1353,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn or_else<F>(self, f: F) -> Option<T>
|
||||
where
|
||||
F: ~const FnOnce() -> Option<T>,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Some(x) => Some(x),
|
||||
|
@ -1375,9 +1389,10 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "option_xor", since = "1.37.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn xor(self, optb: Option<T>) -> Option<T>
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match (self, optb) {
|
||||
(Some(a), None) => Some(a),
|
||||
|
@ -1413,9 +1428,10 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "option_insert", since = "1.53.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn insert(&mut self, value: T) -> &mut T
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
{
|
||||
*self = Some(value);
|
||||
|
||||
|
@ -1446,9 +1462,10 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "option_entry", since = "1.20.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn get_or_insert(&mut self, value: T) -> &mut T
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
{
|
||||
if let None = *self {
|
||||
*self = Some(value);
|
||||
|
@ -1513,10 +1530,11 @@ impl<T> Option<T> {
|
|||
#[inline]
|
||||
#[stable(feature = "option_entry", since = "1.20.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
|
||||
where
|
||||
F: ~const FnOnce() -> T,
|
||||
F: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
if let None = *self {
|
||||
// the compiler isn't smart enough to know that we are not dropping a `T`
|
||||
|
@ -1627,10 +1645,11 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[stable(feature = "option_zip_option", since = "1.46.0")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
|
||||
where
|
||||
T: ~const Drop,
|
||||
U: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
U: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match (self, other) {
|
||||
(Some(a), Some(b)) => Some((a, b)),
|
||||
|
@ -1668,12 +1687,13 @@ impl<T> Option<T> {
|
|||
/// ```
|
||||
#[unstable(feature = "option_zip", issue = "70086")]
|
||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
|
||||
where
|
||||
F: ~const FnOnce(T, U) -> R,
|
||||
F: ~const Drop,
|
||||
T: ~const Drop,
|
||||
U: ~const Drop,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
U: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match (self, other) {
|
||||
(Some(a), Some(b)) => Some(f(a, b)),
|
||||
|
@ -1860,9 +1880,10 @@ const fn expect_failed(msg: &str) -> ! {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
impl<T> const Clone for Option<T>
|
||||
where
|
||||
T: ~const Clone + ~const Drop,
|
||||
T: ~const Clone + ~const Drop + ~const Destruct,
|
||||
{
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
|
|
|
@ -490,6 +490,7 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
|
||||
use crate::marker::Destruct;
|
||||
use crate::ops::{self, ControlFlow, Deref, DerefMut};
|
||||
use crate::{convert, fmt, hint};
|
||||
|
||||
|
@ -635,7 +636,7 @@ impl<T, E> Result<T, E> {
|
|||
#[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
|
||||
pub const fn ok(self) -> Option<T>
|
||||
where
|
||||
E: ~const Drop,
|
||||
E: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Ok(x) => Some(x),
|
||||
|
@ -666,7 +667,7 @@ impl<T, E> Result<T, E> {
|
|||
#[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
|
||||
pub const fn err(self) -> Option<E>
|
||||
where
|
||||
T: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
// FIXME: ~const Drop doesn't quite work right yet
|
||||
|
@ -1282,9 +1283,9 @@ impl<T, E> Result<T, E> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E>
|
||||
where
|
||||
T: ~const Drop,
|
||||
U: ~const Drop,
|
||||
E: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
U: ~const Drop + ~const Destruct,
|
||||
E: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
// FIXME: ~const Drop doesn't quite work right yet
|
||||
|
@ -1367,9 +1368,9 @@ impl<T, E> Result<T, E> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F>
|
||||
where
|
||||
T: ~const Drop,
|
||||
E: ~const Drop,
|
||||
F: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
E: ~const Drop + ~const Destruct,
|
||||
F: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Ok(v) => Ok(v),
|
||||
|
@ -1431,8 +1432,8 @@ impl<T, E> Result<T, E> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const fn unwrap_or(self, default: T) -> T
|
||||
where
|
||||
T: ~const Drop,
|
||||
E: ~const Drop,
|
||||
T: ~const Drop + ~const Destruct,
|
||||
E: ~const Drop + ~const Destruct,
|
||||
{
|
||||
match self {
|
||||
Ok(t) => t,
|
||||
|
@ -1802,10 +1803,11 @@ fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
|
||||
#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
|
||||
impl<T, E> const Clone for Result<T, E>
|
||||
where
|
||||
T: ~const Clone + ~const Drop,
|
||||
E: ~const Clone + ~const Drop,
|
||||
T: ~const Clone + ~const Drop + ~const Destruct,
|
||||
E: ~const Clone + ~const Drop + ~const Destruct,
|
||||
{
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
|
|
|
@ -121,11 +121,20 @@ impl Clean<Option<GenericBound>> for hir::GenericBound<'_> {
|
|||
hir::GenericBound::Trait(ref t, modifier) => {
|
||||
// `T: ~const Drop` is not equivalent to `T: Drop`, and we don't currently document `~const` bounds
|
||||
// because of its experimental status, so just don't show these.
|
||||
if Some(t.trait_ref.trait_def_id().unwrap()) == cx.tcx.lang_items().drop_trait()
|
||||
&& hir::TraitBoundModifier::MaybeConst == modifier
|
||||
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
|
||||
if modifier == hir::TraitBoundModifier::MaybeConst
|
||||
&& [cx.tcx.lang_items().drop_trait(), cx.tcx.lang_items().destruct_trait()]
|
||||
.iter()
|
||||
.any(|tr| *tr == Some(t.trait_ref.trait_def_id().unwrap()))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
{
|
||||
// FIXME: remove `lang_items().drop_trait()` from above logic,
|
||||
// as well as the comment about `~const Drop` because it was renamed to `Destruct`.
|
||||
}
|
||||
GenericBound::TraitBound(t.clean(cx), modifier)
|
||||
}
|
||||
})
|
||||
|
@ -306,12 +315,21 @@ impl<'a> Clean<Option<WherePredicate>> for ty::PolyTraitPredicate<'a> {
|
|||
fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> {
|
||||
// `T: ~const Drop` is not equivalent to `T: Drop`, and we don't currently document `~const` bounds
|
||||
// because of its experimental status, so just don't show these.
|
||||
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
|
||||
if self.skip_binder().constness == ty::BoundConstness::ConstIfConst
|
||||
&& Some(self.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().drop_trait()
|
||||
&& [cx.tcx.lang_items().drop_trait(), cx.tcx.lang_items().destruct_trait()]
|
||||
.iter()
|
||||
.any(|tr| *tr == Some(self.skip_binder().def_id()))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
{
|
||||
// FIXME: remove `lang_items().drop_trait()` from above logic,
|
||||
// as well as the comment about `~const Drop` because it was renamed to `Destruct`.
|
||||
}
|
||||
|
||||
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
|
||||
Some(WherePredicate::BoundPredicate {
|
||||
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#![allow(unused)]
|
||||
#![feature(const_trait_impl, inline_const, negative_impls)]
|
||||
|
||||
const fn f<T: ~const Drop>(x: T) {}
|
||||
use std::marker::Destruct;
|
||||
|
||||
const fn f<T: ~const Destruct>(x: T) {}
|
||||
|
||||
struct UnconstDrop;
|
||||
|
||||
|
@ -16,8 +18,8 @@ impl !Drop for NonDrop {}
|
|||
fn main() {
|
||||
const {
|
||||
f(UnconstDrop);
|
||||
//~^ ERROR the trait bound `UnconstDrop: ~const Drop` is not satisfied
|
||||
//~^ ERROR can't drop
|
||||
f(NonDrop);
|
||||
//~^ ERROR the trait bound `NonDrop: ~const Drop` is not satisfied
|
||||
//~^ ERROR can't drop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
error[E0277]: the trait bound `UnconstDrop: ~const Drop` is not satisfied
|
||||
--> $DIR/const-block-const-bound.rs:18:11
|
||||
error[E0277]: can't drop `UnconstDrop` in const contexts
|
||||
--> $DIR/const-block-const-bound.rs:20:11
|
||||
|
|
||||
LL | f(UnconstDrop);
|
||||
| - ^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
||||
| - ^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: the trait bound `UnconstDrop: ~const Destruct` is not satisfied
|
||||
note: required by a bound in `f`
|
||||
--> $DIR/const-block-const-bound.rs:4:15
|
||||
--> $DIR/const-block-const-bound.rs:6:15
|
||||
|
|
||||
LL | const fn f<T: ~const Drop>(x: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `f`
|
||||
LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `f`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | f(&UnconstDrop);
|
||||
|
@ -18,19 +19,20 @@ LL | f(&UnconstDrop);
|
|||
LL | f(&mut UnconstDrop);
|
||||
| ++++
|
||||
|
||||
error[E0277]: the trait bound `NonDrop: ~const Drop` is not satisfied
|
||||
--> $DIR/const-block-const-bound.rs:20:11
|
||||
error[E0277]: can't drop `NonDrop` in const contexts
|
||||
--> $DIR/const-block-const-bound.rs:22:11
|
||||
|
|
||||
LL | f(NonDrop);
|
||||
| - ^^^^^^^ expected an implementor of trait `~const Drop`
|
||||
| - ^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: the trait bound `NonDrop: ~const Destruct` is not satisfied
|
||||
note: required by a bound in `f`
|
||||
--> $DIR/const-block-const-bound.rs:4:15
|
||||
--> $DIR/const-block-const-bound.rs:6:15
|
||||
|
|
||||
LL | const fn f<T: ~const Drop>(x: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `f`
|
||||
LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `f`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | f(&NonDrop);
|
||||
|
|
|
@ -48,7 +48,7 @@ LL | const_eval_select((), 42, 0xDEADBEEF);
|
|||
note: required by a bound in `const_eval_select`
|
||||
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||
|
|
||||
LL | G: FnOnce<ARG, Output = RET> + ~const Drop,
|
||||
LL | G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||
|
||||
error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
|
||||
|
@ -60,7 +60,7 @@ LL | const_eval_select((1,), foo, bar);
|
|||
note: required by a bound in `const_eval_select`
|
||||
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||
|
|
||||
LL | G: FnOnce<ARG, Output = RET> + ~const Drop,
|
||||
LL | G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
|
||||
| ^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||
|
||||
error[E0631]: type mismatch in function arguments
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
#![feature(const_trait_impl)]
|
||||
#![feature(const_precise_live_drops)]
|
||||
|
||||
const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Drop {
|
||||
use std::marker::Destruct;
|
||||
|
||||
const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
|
||||
match res {
|
||||
Ok(t) => Some(t),
|
||||
Err(_e) => None,
|
||||
|
@ -12,7 +14,7 @@ const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Drop {
|
|||
|
||||
pub struct Foo<T>(T);
|
||||
|
||||
const fn baz<T: ~const Drop, E: ~const Drop>(res: Result<Foo<T>, Foo<E>>) -> Option<Foo<T>> {
|
||||
const fn baz<T: ~const Destruct, E: ~const Destruct>(res: Result<Foo<T>, Foo<E>>) -> Option<Foo<T>> {
|
||||
foo(res)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied
|
||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
||||
--> $DIR/const-drop-fail.rs:43:5
|
||||
|
|
||||
LL | const _: () = check($exp);
|
||||
| ----- required by a bound introduced by this call
|
||||
...
|
||||
LL | NonTrivialDrop,
|
||||
| ^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
||||
| ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
|
|
||||
= note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
|
||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | &NonTrivialDrop,
|
||||
|
@ -19,16 +20,16 @@ LL | &NonTrivialDrop,
|
|||
LL | &mut NonTrivialDrop,
|
||||
| ++++
|
||||
|
||||
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied in `ConstImplWithDropGlue`
|
||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
||||
--> $DIR/const-drop-fail.rs:45:5
|
||||
|
|
||||
LL | const _: () = check($exp);
|
||||
| ----- required by a bound introduced by this call
|
||||
...
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
||||
|
|
||||
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||
--> $DIR/const-drop-fail.rs:45:5
|
||||
|
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
|
@ -41,28 +42,24 @@ LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
|||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
|
||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
|
||||
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Drop` is not satisfied
|
||||
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
|
||||
--> $DIR/const-drop-fail.rs:47:5
|
||||
|
|
||||
LL | const _: () = check($exp);
|
||||
| ----- required by a bound introduced by this call
|
||||
...
|
||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
|
|
||||
note: required because of the requirements on the impl of `~const Drop` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
--> $DIR/const-drop-fail.rs:28:25
|
||||
|
|
||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
|
||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#![feature(const_mut_refs)]
|
||||
#![cfg_attr(precise, feature(const_precise_live_drops))]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::marker::{Destruct, PhantomData};
|
||||
|
||||
struct NonTrivialDrop;
|
||||
|
||||
|
@ -31,7 +31,7 @@ impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
|||
}
|
||||
}
|
||||
|
||||
const fn check<T: ~const Drop>(_: T) {}
|
||||
const fn check<T: ~const Destruct>(_: T) {}
|
||||
|
||||
macro_rules! check_all {
|
||||
($($exp:expr),*$(,)?) => {$(
|
||||
|
@ -41,9 +41,9 @@ macro_rules! check_all {
|
|||
|
||||
check_all! {
|
||||
NonTrivialDrop,
|
||||
//~^ ERROR the trait bound
|
||||
//~^ ERROR can't drop
|
||||
ConstImplWithDropGlue(NonTrivialDrop),
|
||||
//~^ ERROR the trait bound
|
||||
//~^ ERROR can't drop
|
||||
ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||
//~^ ERROR the trait bound
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied
|
||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
||||
--> $DIR/const-drop-fail.rs:43:5
|
||||
|
|
||||
LL | const _: () = check($exp);
|
||||
| ----- required by a bound introduced by this call
|
||||
...
|
||||
LL | NonTrivialDrop,
|
||||
| ^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
||||
| ^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
|
|
||||
= note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
|
||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | &NonTrivialDrop,
|
||||
|
@ -19,16 +20,16 @@ LL | &NonTrivialDrop,
|
|||
LL | &mut NonTrivialDrop,
|
||||
| ++++
|
||||
|
||||
error[E0277]: the trait bound `NonTrivialDrop: ~const Drop` is not satisfied in `ConstImplWithDropGlue`
|
||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
||||
--> $DIR/const-drop-fail.rs:45:5
|
||||
|
|
||||
LL | const _: () = check($exp);
|
||||
| ----- required by a bound introduced by this call
|
||||
...
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
||||
|
|
||||
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||
--> $DIR/const-drop-fail.rs:45:5
|
||||
|
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
|
@ -41,28 +42,24 @@ LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
|||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
|
||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
|
||||
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Drop` is not satisfied
|
||||
error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
|
||||
--> $DIR/const-drop-fail.rs:47:5
|
||||
|
|
||||
LL | const _: () = check($exp);
|
||||
| ----- required by a bound introduced by this call
|
||||
...
|
||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Drop`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
|
||||
|
|
||||
note: required because of the requirements on the impl of `~const Drop` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
--> $DIR/const-drop-fail.rs:28:25
|
||||
|
|
||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const-drop-fail.rs:34:19
|
||||
|
|
||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
||||
| ^^^^^^^^^^^ required by this bound in `check`
|
||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#![feature(never_type)]
|
||||
#![cfg_attr(precise, feature(const_precise_live_drops))]
|
||||
|
||||
use std::marker::Destruct;
|
||||
|
||||
struct S<'a>(&'a mut u8);
|
||||
|
||||
impl<'a> const Drop for S<'a> {
|
||||
|
@ -13,7 +15,7 @@ impl<'a> const Drop for S<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
const fn a<T: ~const Drop>(_: T) {}
|
||||
const fn a<T: ~const Destruct>(_: T) {}
|
||||
|
||||
const fn b() -> u8 {
|
||||
let mut c = 0;
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
// Regression test for #92111.
|
||||
//
|
||||
// The issue was that we normalize trait bounds before caching
|
||||
// results of selection. Checking that `impl Tr for S` requires
|
||||
// checking `S: !Drop` because it cannot overlap with the blanket
|
||||
// impl. Then we save the (unsatisfied) result from checking `S: Drop`.
|
||||
// Then the call to `a` checks whether `S: ~const Drop` but we normalize
|
||||
// it to `S: Drop` which the cache claims to be unsatisfied.
|
||||
//
|
||||
// check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
use std::marker::Destruct;
|
||||
|
||||
pub trait Tr {}
|
||||
|
||||
#[allow(drop_bounds)]
|
||||
|
@ -21,7 +16,7 @@ pub struct S(i32);
|
|||
|
||||
impl Tr for S {}
|
||||
|
||||
const fn a<T: ~const Drop>(t: T) {}
|
||||
const fn a<T: ~const Destruct>(t: T) {}
|
||||
|
||||
fn main() {
|
||||
a(S(0));
|
||||
|
|
Loading…
Add table
Reference in a new issue