mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Auto merge of #94901 - fee1-dead:destructable, r=oli-obk
Rename `~const Drop` to `~const Destruct` r? `@oli-obk` Completely switching to `~const Destructible` would be rather complicated, so it seems best to add it for now and wait for it to be backported to beta in the next release. The rationale is to prevent complications such as #92149 and #94803 by introducing an entirely new trait. And `~const Destructible` reads a bit better than `~const Drop`. Name Bikesheddable.
This commit is contained in:
commit
9280445570
@ -3,6 +3,7 @@
|
|||||||
//! See the `Qualif` trait for more info.
|
//! See the `Qualif` trait for more info.
|
||||||
|
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
|
use rustc_hir::LangItem;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::TraitEngine;
|
use rustc_infer::traits::TraitEngine;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
@ -152,18 +153,14 @@ impl Qualif for NeedsNonConstDrop {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(drop_trait) = cx.tcx.lang_items().drop_trait() else {
|
let destruct = cx.tcx.require_lang_item(LangItem::Destruct, None);
|
||||||
// there is no way to define a type that needs non-const drop
|
|
||||||
// without having the lang item present.
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
let obligation = Obligation::new(
|
let obligation = Obligation::new(
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
cx.param_env,
|
cx.param_env,
|
||||||
ty::Binder::dummy(ty::TraitPredicate {
|
ty::Binder::dummy(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: ty::TraitRef {
|
||||||
def_id: drop_trait,
|
def_id: destruct,
|
||||||
substs: cx.tcx.mk_substs_trait(ty, &[]),
|
substs: cx.tcx.mk_substs_trait(ty, &[]),
|
||||||
},
|
},
|
||||||
constness: ty::BoundConstness::ConstIfConst,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
@ -174,15 +171,16 @@ impl Qualif for NeedsNonConstDrop {
|
|||||||
cx.tcx.infer_ctxt().enter(|infcx| {
|
cx.tcx.infer_ctxt().enter(|infcx| {
|
||||||
let mut selcx = SelectionContext::new(&infcx);
|
let mut selcx = SelectionContext::new(&infcx);
|
||||||
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
|
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;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !matches!(
|
if !matches!(
|
||||||
impl_src,
|
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
|
// then it's bad
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -216,6 +216,7 @@ language_item_table! {
|
|||||||
Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0);
|
Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||||
|
|
||||||
Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None;
|
Drop, sym::drop, drop_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);
|
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);
|
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 {
|
let Trait(trait_predicate) = predicate.kind().skip_binder() else {
|
||||||
continue
|
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;
|
let def_id = trait_predicate.trait_ref.def_id;
|
||||||
if cx.tcx.lang_items().drop_trait() == Some(def_id) {
|
if cx.tcx.lang_items().drop_trait() == Some(def_id) {
|
||||||
// Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern.
|
// Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern.
|
||||||
|
@ -577,7 +577,7 @@ pub enum ImplSource<'tcx, N> {
|
|||||||
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
|
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
|
||||||
|
|
||||||
/// ImplSource for a `const Drop` implementation.
|
/// ImplSource for a `const Drop` implementation.
|
||||||
ConstDrop(ImplSourceConstDropData<N>),
|
ConstDestruct(ImplSourceConstDestructData<N>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, N> ImplSource<'tcx, N> {
|
impl<'tcx, N> ImplSource<'tcx, N> {
|
||||||
@ -595,7 +595,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||||||
| ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(),
|
| ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(),
|
||||||
ImplSource::TraitAlias(d) => d.nested,
|
ImplSource::TraitAlias(d) => d.nested,
|
||||||
ImplSource::TraitUpcasting(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::Pointee(ImplSourcePointeeData) => &[],
|
||||||
ImplSource::TraitAlias(d) => &d.nested,
|
ImplSource::TraitAlias(d) => &d.nested,
|
||||||
ImplSource::TraitUpcasting(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(),
|
nested: d.nested.into_iter().map(f).collect(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ImplSource::ConstDrop(i) => ImplSource::ConstDrop(ImplSourceConstDropData {
|
ImplSource::ConstDestruct(i) => {
|
||||||
nested: i.nested.into_iter().map(f).collect(),
|
ImplSource::ConstDestruct(ImplSourceConstDestructData {
|
||||||
}),
|
nested: i.nested.into_iter().map(f).collect(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -767,7 +769,7 @@ pub struct ImplSourceDiscriminantKindData;
|
|||||||
pub struct ImplSourcePointeeData;
|
pub struct ImplSourcePointeeData;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
|
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)]
|
||||||
pub struct ImplSourceConstDropData<N> {
|
pub struct ImplSourceConstDestructData<N> {
|
||||||
pub nested: Vec<N>,
|
pub nested: Vec<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,8 +146,8 @@ pub enum SelectionCandidate<'tcx> {
|
|||||||
|
|
||||||
BuiltinUnsizeCandidate,
|
BuiltinUnsizeCandidate,
|
||||||
|
|
||||||
/// Implementation of `const Drop`, optionally from a custom `impl const Drop`.
|
/// Implementation of `const Destruct`, optionally from a custom `impl const Drop`.
|
||||||
ConstDropCandidate(Option<DefId>),
|
ConstDestructCandidate(Option<DefId>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of trait evaluation. The order is important
|
/// 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::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 {
|
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()) {
|
if unlikely!(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) {
|
||||||
// remap without changing constness of this predicate.
|
// remap without changing constness of this predicate.
|
||||||
// this is because `T: ~const Drop` has a different meaning to `T: Drop`
|
// 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)
|
param_env.remap_constness_with(self.constness)
|
||||||
} else {
|
} else {
|
||||||
*param_env = param_env.with_constness(self.constness.and(param_env.constness()))
|
*param_env = param_env.with_constness(self.constness.and(param_env.constness()))
|
||||||
|
@ -571,6 +571,7 @@ symbols! {
|
|||||||
deref_target,
|
deref_target,
|
||||||
derive,
|
derive,
|
||||||
derive_default_enum,
|
derive_default_enum,
|
||||||
|
destruct,
|
||||||
destructuring_assignment,
|
destructuring_assignment,
|
||||||
diagnostic,
|
diagnostic,
|
||||||
direct,
|
direct,
|
||||||
|
@ -1569,7 +1569,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||||||
super::ImplSource::AutoImpl(..)
|
super::ImplSource::AutoImpl(..)
|
||||||
| super::ImplSource::Builtin(..)
|
| super::ImplSource::Builtin(..)
|
||||||
| super::ImplSource::TraitUpcasting(_)
|
| super::ImplSource::TraitUpcasting(_)
|
||||||
| super::ImplSource::ConstDrop(_) => {
|
| super::ImplSource::ConstDestruct(_) => {
|
||||||
// These traits have no associated types.
|
// These traits have no associated types.
|
||||||
selcx.tcx().sess.delay_span_bug(
|
selcx.tcx().sess.delay_span_bug(
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
@ -1644,7 +1644,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
|
|||||||
| super::ImplSource::Builtin(..)
|
| super::ImplSource::Builtin(..)
|
||||||
| super::ImplSource::TraitUpcasting(_)
|
| super::ImplSource::TraitUpcasting(_)
|
||||||
| super::ImplSource::TraitAlias(..)
|
| super::ImplSource::TraitAlias(..)
|
||||||
| super::ImplSource::ConstDrop(_) => {
|
| super::ImplSource::ConstDestruct(_) => {
|
||||||
// we don't create Select candidates with this kind of resolution
|
// we don't create Select candidates with this kind of resolution
|
||||||
span_bug!(
|
span_bug!(
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
//! candidates. See the [rustc dev guide] for more details.
|
//! candidates. See the [rustc dev guide] for more details.
|
||||||
//!
|
//!
|
||||||
//! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
|
//! [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 as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::TraitEngine;
|
use rustc_infer::traits::TraitEngine;
|
||||||
@ -307,7 +308,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
} else if lang_items.drop_trait() == Some(def_id)
|
} else if lang_items.drop_trait() == Some(def_id)
|
||||||
&& obligation.predicate.is_const_if_const()
|
&& 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 {
|
} else {
|
||||||
if lang_items.clone_trait() == Some(def_id) {
|
if lang_items.clone_trait() == Some(def_id) {
|
||||||
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
|
// 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,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'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.
|
// to check anything. We'll short-circuit checking any obligations in confirmation, too.
|
||||||
if obligation.param_env.constness() == hir::Constness::NotConst {
|
if !obligation.is_const() {
|
||||||
candidates.vec.push(ConstDropCandidate(None));
|
candidates.vec.push(ConstDestructCandidate(None));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,7 +937,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| ty::Param(_)
|
| ty::Param(_)
|
||||||
| ty::Placeholder(_)
|
| ty::Placeholder(_)
|
||||||
| ty::Projection(_) => {
|
| 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.
|
// not structurally... so don't push a candidate.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,14 +961,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| ty::Generator(..)
|
| ty::Generator(..)
|
||||||
| ty::Tuple(_)
|
| ty::Tuple(_)
|
||||||
| ty::GeneratorWitness(_) => {
|
| ty::GeneratorWitness(_) => {
|
||||||
// These are built-in, and cannot have a custom `impl const Drop`.
|
// These are built-in, and cannot have a custom `impl const Destruct`.
|
||||||
candidates.vec.push(ConstDropCandidate(None));
|
candidates.vec.push(ConstDestructCandidate(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Adt(..) => {
|
ty::Adt(..) => {
|
||||||
// Find a custom `impl Drop` impl, if it exists
|
// Find a custom `impl Drop` impl, if it exists
|
||||||
let relevant_impl = self.tcx().find_map_relevant_impl(
|
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(),
|
obligation.predicate.skip_binder().trait_ref.self_ty(),
|
||||||
Some,
|
Some,
|
||||||
);
|
);
|
||||||
@ -966,11 +976,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
if let Some(impl_def_id) = relevant_impl {
|
if let Some(impl_def_id) = relevant_impl {
|
||||||
// Check that `impl Drop` is actually const, if there is a custom 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 {
|
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 {
|
} else {
|
||||||
// Otherwise check the ADT like a built-in type (structurally)
|
// 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
|
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::Constness;
|
|
||||||
use rustc_index::bit_set::GrowableBitSet;
|
use rustc_index::bit_set::GrowableBitSet;
|
||||||
use rustc_infer::infer::InferOk;
|
use rustc_infer::infer::InferOk;
|
||||||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||||
@ -29,9 +28,9 @@ use crate::traits::TraitNotObjectSafe;
|
|||||||
use crate::traits::VtblSegment;
|
use crate::traits::VtblSegment;
|
||||||
use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
|
use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation};
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, ImplSourceConstDropData,
|
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||||
ImplSourceDiscriminantKindData, ImplSourceFnPointerData, ImplSourceGeneratorData,
|
ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||||
ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData,
|
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData,
|
||||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData,
|
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData,
|
||||||
};
|
};
|
||||||
use crate::traits::{ObjectCastObligation, PredicateObligation, TraitObligation};
|
use crate::traits::{ObjectCastObligation, PredicateObligation, TraitObligation};
|
||||||
@ -156,9 +155,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
Ok(ImplSource::TraitUpcasting(data))
|
Ok(ImplSource::TraitUpcasting(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstDropCandidate(def_id) => {
|
ConstDestructCandidate(def_id) => {
|
||||||
let data = self.confirm_const_drop_candidate(obligation, def_id)?;
|
let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
|
||||||
Ok(ImplSource::ConstDrop(data))
|
Ok(ImplSource::ConstDestruct(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1037,14 +1036,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
Ok(ImplSourceBuiltinData { nested })
|
Ok(ImplSourceBuiltinData { nested })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_const_drop_candidate(
|
fn confirm_const_destruct_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
impl_def_id: Option<DefId>,
|
impl_def_id: Option<DefId>,
|
||||||
) -> Result<ImplSourceConstDropData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<ImplSourceConstDestructData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||||
// `~const Drop` in a non-const environment is always trivially true, since our type is `Drop`
|
// `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
|
||||||
if obligation.param_env.constness() == Constness::NotConst {
|
if !obligation.is_const() {
|
||||||
return Ok(ImplSourceConstDropData { nested: vec![] });
|
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();
|
let tcx = self.tcx();
|
||||||
@ -1054,9 +1062,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||||
|
|
||||||
// If we have a custom `impl const Drop`, then
|
// 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 {
|
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
|
// We want to confirm the ADT's fields if we have an ADT
|
||||||
@ -1114,7 +1142,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
self_ty
|
self_ty
|
||||||
.rebind(ty::TraitPredicate {
|
.rebind(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
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, &[]),
|
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||||
},
|
},
|
||||||
constness: ty::BoundConstness::ConstIfConst,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
@ -1140,7 +1170,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
let predicate = self_ty
|
let predicate = self_ty
|
||||||
.rebind(ty::TraitPredicate {
|
.rebind(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
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, &[]),
|
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||||
},
|
},
|
||||||
constness: ty::BoundConstness::ConstIfConst,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
@ -1158,6 +1188,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ImplSourceConstDropData { nested })
|
Ok(ImplSourceConstDestructData { nested })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1179,7 +1179,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
GeneratorCandidate => {}
|
GeneratorCandidate => {}
|
||||||
// FnDef where the function is const
|
// FnDef where the function is const
|
||||||
FnPointerCandidate { is_const: true } => {}
|
FnPointerCandidate { is_const: true } => {}
|
||||||
ConstDropCandidate(_) => {}
|
ConstDestructCandidate(_) => {}
|
||||||
_ => {
|
_ => {
|
||||||
// reject all other types of candidates
|
// reject all other types of candidates
|
||||||
continue;
|
continue;
|
||||||
@ -1589,7 +1589,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
|
// (*) 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
|
// This is a fix for #53123 and prevents winnowing from accidentally extending the
|
||||||
// lifetime of a variable.
|
// lifetime of a variable.
|
||||||
@ -1606,7 +1606,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
BuiltinCandidate { has_nested: false }
|
BuiltinCandidate { has_nested: false }
|
||||||
| DiscriminantKindCandidate
|
| DiscriminantKindCandidate
|
||||||
| PointeeCandidate
|
| PointeeCandidate
|
||||||
| ConstDropCandidate(_),
|
| ConstDestructCandidate(_),
|
||||||
_,
|
_,
|
||||||
) => true,
|
) => true,
|
||||||
(
|
(
|
||||||
@ -1614,7 +1614,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
BuiltinCandidate { has_nested: false }
|
BuiltinCandidate { has_nested: false }
|
||||||
| DiscriminantKindCandidate
|
| DiscriminantKindCandidate
|
||||||
| PointeeCandidate
|
| PointeeCandidate
|
||||||
| ConstDropCandidate(_),
|
| ConstDestructCandidate(_),
|
||||||
) => false,
|
) => false,
|
||||||
|
|
||||||
(ParamCandidate(other), ParamCandidate(victim)) => {
|
(ParamCandidate(other), ParamCandidate(victim)) => {
|
||||||
|
@ -378,7 +378,7 @@ fn resolve_associated_item<'tcx>(
|
|||||||
| traits::ImplSource::DiscriminantKind(..)
|
| traits::ImplSource::DiscriminantKind(..)
|
||||||
| traits::ImplSource::Pointee(..)
|
| traits::ImplSource::Pointee(..)
|
||||||
| traits::ImplSource::TraitUpcasting(_)
|
| traits::ImplSource::TraitUpcasting(_)
|
||||||
| traits::ImplSource::ConstDrop(_) => None,
|
| traits::ImplSource::ConstDestruct(_) => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ use core::ptr::{self, NonNull};
|
|||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use core::alloc::*;
|
pub use core::alloc::*;
|
||||||
|
|
||||||
|
use core::marker::Destruct;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
@ -324,12 +326,16 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
|
|||||||
#[cfg_attr(not(test), lang = "box_free")]
|
#[cfg_attr(not(test), lang = "box_free")]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
#[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.
|
// 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
|
// When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
|
||||||
// well.
|
// well.
|
||||||
// For example if `Box` is changed to `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
|
// 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.
|
// 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>,
|
ptr: Unique<T>,
|
||||||
alloc: A,
|
alloc: A,
|
||||||
) {
|
) {
|
||||||
|
@ -331,6 +331,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
#[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>
|
impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
|
||||||
where
|
where
|
||||||
B::Owned: ~const Borrow<B>,
|
B::Owned: ~const Borrow<B>,
|
||||||
|
@ -143,7 +143,7 @@ use core::hash::{Hash, Hasher};
|
|||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use core::iter::FromIterator;
|
use core::iter::FromIterator;
|
||||||
use core::iter::{FusedIterator, Iterator};
|
use core::iter::{FusedIterator, Iterator};
|
||||||
use core::marker::{Unpin, Unsize};
|
use core::marker::{Destruct, Unpin, Unsize};
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::ops::{
|
use core::ops::{
|
||||||
CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver,
|
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")]
|
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[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
|
pub const fn new_in(x: T, alloc: A) -> Self
|
||||||
where
|
where
|
||||||
A: ~const Allocator + ~const Drop,
|
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
let mut boxed = Self::new_uninit_in(alloc);
|
let mut boxed = Self::new_uninit_in(alloc);
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -378,10 +379,11 @@ impl<T, A: Allocator> Box<T, A> {
|
|||||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||||
#[inline]
|
#[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>
|
pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
A: ~const Allocator + ~const Drop,
|
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
let mut boxed = Self::try_new_uninit_in(alloc)?;
|
let mut boxed = Self::try_new_uninit_in(alloc)?;
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -415,9 +417,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
// #[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>
|
pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
|
||||||
where
|
where
|
||||||
A: ~const Allocator + ~const Drop,
|
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||||
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
|
// 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 = "allocator_api", issue = "32838")]
|
||||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
#[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>
|
pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
|
||||||
where
|
where
|
||||||
A: ~const Allocator + ~const Drop,
|
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||||
let ptr = alloc.allocate(layout)?.cast();
|
let ptr = alloc.allocate(layout)?.cast();
|
||||||
@ -487,9 +491,10 @@ impl<T, A: Allocator> Box<T, A> {
|
|||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
#[must_use]
|
#[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>
|
pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
|
||||||
where
|
where
|
||||||
A: ~const Allocator + ~const Drop,
|
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||||
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
|
// 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 = "allocator_api", issue = "32838")]
|
||||||
// #[unstable(feature = "new_uninit", issue = "63291")]
|
// #[unstable(feature = "new_uninit", issue = "63291")]
|
||||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
#[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>
|
pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
|
||||||
where
|
where
|
||||||
A: ~const Allocator + ~const Drop,
|
A: ~const Allocator + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
let layout = Layout::new::<mem::MaybeUninit<T>>();
|
||||||
let ptr = alloc.allocate_zeroed(layout)?.cast();
|
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")]
|
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline(always)]
|
#[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>
|
pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
|
||||||
where
|
where
|
||||||
A: 'static + ~const Allocator + ~const Drop,
|
A: 'static + ~const Allocator + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
Self::into_pin(Self::new_in(x, alloc))
|
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")]
|
#[unstable(feature = "box_into_inner", issue = "80437")]
|
||||||
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
|
||||||
#[inline]
|
#[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
|
pub const fn into_inner(boxed: Self) -> T
|
||||||
where
|
where
|
||||||
Self: ~const Drop,
|
Self: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
*boxed
|
*boxed
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//! impl bool {}
|
//! impl bool {}
|
||||||
|
|
||||||
|
use crate::marker::Destruct;
|
||||||
|
|
||||||
#[lang = "bool"]
|
#[lang = "bool"]
|
||||||
impl bool {
|
impl bool {
|
||||||
/// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html),
|
/// 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")]
|
#[unstable(feature = "bool_to_option", issue = "80967")]
|
||||||
#[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
|
#[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
|
||||||
#[inline]
|
#[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>
|
pub const fn then_some<T>(self, t: T) -> Option<T>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
if self { Some(t) } else { None }
|
if self { Some(t) } else { None }
|
||||||
}
|
}
|
||||||
@ -35,10 +38,11 @@ impl bool {
|
|||||||
#[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
|
#[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
|
||||||
#[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
|
#[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
|
||||||
#[inline]
|
#[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>
|
pub const fn then<T, F>(self, f: F) -> Option<T>
|
||||||
where
|
where
|
||||||
F: ~const FnOnce() -> T,
|
F: ~const FnOnce() -> T,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
if self { Some(f()) } else { None }
|
if self { Some(f()) } else { None }
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
|
use crate::marker::Destruct;
|
||||||
|
|
||||||
/// A common trait for the ability to explicitly duplicate an object.
|
/// 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
|
/// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while
|
||||||
@ -128,9 +130,10 @@ pub trait Clone: Sized {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[default_method_body_is_const]
|
#[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)
|
fn clone_from(&mut self, source: &Self)
|
||||||
where
|
where
|
||||||
Self: ~const Drop,
|
Self: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
*self = source.clone()
|
*self = source.clone()
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
)]
|
)]
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
use crate::marker::DiscriminantKind;
|
use crate::marker::{Destruct, DiscriminantKind};
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
|
|
||||||
// These imports are used for simplifying intra-doc links
|
// 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")]
|
#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
|
||||||
#[lang = "const_eval_select"]
|
#[lang = "const_eval_select"]
|
||||||
#[rustc_do_not_const_check]
|
#[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>(
|
pub const unsafe fn const_eval_select<ARG, F, G, RET>(
|
||||||
arg: ARG,
|
arg: ARG,
|
||||||
_called_in_const: F,
|
_called_in_const: F,
|
||||||
@ -2360,7 +2361,7 @@ pub const unsafe fn const_eval_select<ARG, F, G, RET>(
|
|||||||
) -> RET
|
) -> RET
|
||||||
where
|
where
|
||||||
F: ~const FnOnce<ARG, Output = RET>,
|
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)
|
called_at_rt.call_once(arg)
|
||||||
}
|
}
|
||||||
@ -2372,6 +2373,7 @@ where
|
|||||||
)]
|
)]
|
||||||
#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
|
#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
|
||||||
#[lang = "const_eval_select_ct"]
|
#[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>(
|
pub const unsafe fn const_eval_select_ct<ARG, F, G, RET>(
|
||||||
arg: ARG,
|
arg: ARG,
|
||||||
called_in_const: F,
|
called_in_const: F,
|
||||||
@ -2379,7 +2381,7 @@ pub const unsafe fn const_eval_select_ct<ARG, F, G, RET>(
|
|||||||
) -> RET
|
) -> RET
|
||||||
where
|
where
|
||||||
F: ~const FnOnce<ARG, Output = RET>,
|
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)
|
called_in_const.call_once(arg)
|
||||||
}
|
}
|
||||||
|
@ -792,6 +792,22 @@ impl<T: ?Sized> Unpin for *const T {}
|
|||||||
#[stable(feature = "pin_raw", since = "1.38.0")]
|
#[stable(feature = "pin_raw", since = "1.38.0")]
|
||||||
impl<T: ?Sized> Unpin for *mut T {}
|
impl<T: ?Sized> Unpin for *mut T {}
|
||||||
|
|
||||||
|
/// A marker for types that can be dropped.
|
||||||
|
///
|
||||||
|
/// 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 = "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.
|
/// Implementations of `Copy` for primitive types.
|
||||||
///
|
///
|
||||||
/// Implementations that cannot be described in Rust
|
/// Implementations that cannot be described in Rust
|
||||||
|
@ -503,6 +503,7 @@
|
|||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
|
use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
|
||||||
|
use crate::marker::Destruct;
|
||||||
use crate::panicking::{panic, panic_str};
|
use crate::panicking::{panic, panic_str};
|
||||||
use crate::pin::Pin;
|
use crate::pin::Pin;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -772,9 +773,10 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn unwrap_or(self, default: T) -> T
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
@ -794,10 +796,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn unwrap_or_else<F>(self, f: F) -> T
|
||||||
where
|
where
|
||||||
F: ~const FnOnce() -> T,
|
F: ~const FnOnce() -> T,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
@ -899,10 +902,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn map<U, F>(self, f: F) -> Option<U>
|
||||||
where
|
where
|
||||||
F: ~const FnOnce(T) -> U,
|
F: ~const FnOnce(T) -> U,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(x) => Some(f(x)),
|
Some(x) => Some(f(x)),
|
||||||
@ -928,10 +932,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "result_option_inspect", issue = "91345")]
|
#[unstable(feature = "result_option_inspect", issue = "91345")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn inspect<F>(self, f: F) -> Self
|
||||||
where
|
where
|
||||||
F: ~const FnOnce(&T),
|
F: ~const FnOnce(&T),
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
if let Some(ref x) = self {
|
if let Some(ref x) = self {
|
||||||
f(x);
|
f(x);
|
||||||
@ -961,11 +966,12 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn map_or<U, F>(self, default: U, f: F) -> U
|
||||||
where
|
where
|
||||||
F: ~const FnOnce(T) -> U,
|
F: ~const FnOnce(T) -> U,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
U: ~const Drop,
|
U: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(t) => f(t),
|
Some(t) => f(t),
|
||||||
@ -990,12 +996,13 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U
|
||||||
where
|
where
|
||||||
D: ~const FnOnce() -> U,
|
D: ~const FnOnce() -> U,
|
||||||
D: ~const Drop,
|
D: ~const Drop + ~const Destruct,
|
||||||
F: ~const FnOnce(T) -> U,
|
F: ~const FnOnce(T) -> U,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(t) => f(t),
|
Some(t) => f(t),
|
||||||
@ -1027,9 +1034,10 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn ok_or<E>(self, err: E) -> Result<T, E>
|
||||||
where
|
where
|
||||||
E: ~const Drop,
|
E: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(v) => Ok(v),
|
Some(v) => Ok(v),
|
||||||
@ -1056,10 +1064,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
|
||||||
where
|
where
|
||||||
F: ~const FnOnce() -> E,
|
F: ~const FnOnce() -> E,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(v) => Ok(v),
|
Some(v) => Ok(v),
|
||||||
@ -1190,10 +1199,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn and<U>(self, optb: Option<U>) -> Option<U>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
U: ~const Drop,
|
U: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(_) => optb,
|
Some(_) => optb,
|
||||||
@ -1232,10 +1242,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn and_then<U, F>(self, f: F) -> Option<U>
|
||||||
where
|
where
|
||||||
F: ~const FnOnce(T) -> Option<U>,
|
F: ~const FnOnce(T) -> Option<U>,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(x) => f(x),
|
Some(x) => f(x),
|
||||||
@ -1270,11 +1281,12 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "option_filter", since = "1.27.0")]
|
#[stable(feature = "option_filter", since = "1.27.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn filter<P>(self, predicate: P) -> Self
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
P: ~const FnOnce(&T) -> bool,
|
P: ~const FnOnce(&T) -> bool,
|
||||||
P: ~const Drop,
|
P: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
if let Some(x) = self {
|
if let Some(x) = self {
|
||||||
if predicate(&x) {
|
if predicate(&x) {
|
||||||
@ -1314,9 +1326,10 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn or(self, optb: Option<T>) -> Option<T>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(x) => Some(x),
|
Some(x) => Some(x),
|
||||||
@ -1340,10 +1353,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn or_else<F>(self, f: F) -> Option<T>
|
||||||
where
|
where
|
||||||
F: ~const FnOnce() -> Option<T>,
|
F: ~const FnOnce() -> Option<T>,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Some(x) => Some(x),
|
Some(x) => Some(x),
|
||||||
@ -1375,9 +1389,10 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "option_xor", since = "1.37.0")]
|
#[stable(feature = "option_xor", since = "1.37.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn xor(self, optb: Option<T>) -> Option<T>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match (self, optb) {
|
match (self, optb) {
|
||||||
(Some(a), None) => Some(a),
|
(Some(a), None) => Some(a),
|
||||||
@ -1413,9 +1428,10 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "option_insert", since = "1.53.0")]
|
#[stable(feature = "option_insert", since = "1.53.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn insert(&mut self, value: T) -> &mut T
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
*self = Some(value);
|
*self = Some(value);
|
||||||
|
|
||||||
@ -1446,9 +1462,10 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "option_entry", since = "1.20.0")]
|
#[stable(feature = "option_entry", since = "1.20.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn get_or_insert(&mut self, value: T) -> &mut T
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
if let None = *self {
|
if let None = *self {
|
||||||
*self = Some(value);
|
*self = Some(value);
|
||||||
@ -1513,10 +1530,11 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "option_entry", since = "1.20.0")]
|
#[stable(feature = "option_entry", since = "1.20.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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
|
pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
|
||||||
where
|
where
|
||||||
F: ~const FnOnce() -> T,
|
F: ~const FnOnce() -> T,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
if let None = *self {
|
if let None = *self {
|
||||||
// the compiler isn't smart enough to know that we are not dropping a `T`
|
// 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")]
|
#[stable(feature = "option_zip_option", since = "1.46.0")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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)>
|
pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
U: ~const Drop,
|
U: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Some(a), Some(b)) => Some((a, b)),
|
(Some(a), Some(b)) => Some((a, b)),
|
||||||
@ -1668,12 +1687,13 @@ impl<T> Option<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "option_zip", issue = "70086")]
|
#[unstable(feature = "option_zip", issue = "70086")]
|
||||||
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
|
#[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>
|
pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
|
||||||
where
|
where
|
||||||
F: ~const FnOnce(T, U) -> R,
|
F: ~const FnOnce(T, U) -> R,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
U: ~const Drop,
|
U: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Some(a), Some(b)) => Some(f(a, b)),
|
(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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
|
#[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>
|
impl<T> const Clone for Option<T>
|
||||||
where
|
where
|
||||||
T: ~const Clone + ~const Drop,
|
T: ~const Clone + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -490,6 +490,7 @@
|
|||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
|
use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
|
||||||
|
use crate::marker::Destruct;
|
||||||
use crate::ops::{self, ControlFlow, Deref, DerefMut};
|
use crate::ops::{self, ControlFlow, Deref, DerefMut};
|
||||||
use crate::{convert, fmt, hint};
|
use crate::{convert, fmt, hint};
|
||||||
|
|
||||||
@ -635,7 +636,7 @@ impl<T, E> Result<T, E> {
|
|||||||
#[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
|
#[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
|
||||||
pub const fn ok(self) -> Option<T>
|
pub const fn ok(self) -> Option<T>
|
||||||
where
|
where
|
||||||
E: ~const Drop,
|
E: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Ok(x) => Some(x),
|
Ok(x) => Some(x),
|
||||||
@ -666,7 +667,7 @@ impl<T, E> Result<T, E> {
|
|||||||
#[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
|
#[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
|
||||||
pub const fn err(self) -> Option<E>
|
pub const fn err(self) -> Option<E>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
// FIXME: ~const Drop doesn't quite work right yet
|
// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E>
|
pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
U: ~const Drop,
|
U: ~const Drop + ~const Destruct,
|
||||||
E: ~const Drop,
|
E: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
// FIXME: ~const Drop doesn't quite work right yet
|
// 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")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F>
|
pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F>
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
E: ~const Drop,
|
E: ~const Drop + ~const Destruct,
|
||||||
F: ~const Drop,
|
F: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Ok(v) => Ok(v),
|
Ok(v) => Ok(v),
|
||||||
@ -1431,8 +1432,8 @@ impl<T, E> Result<T, E> {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub const fn unwrap_or(self, default: T) -> T
|
pub const fn unwrap_or(self, default: T) -> T
|
||||||
where
|
where
|
||||||
T: ~const Drop,
|
T: ~const Drop + ~const Destruct,
|
||||||
E: ~const Drop,
|
E: ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
@ -1802,10 +1803,11 @@ fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
|
#[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>
|
impl<T, E> const Clone for Result<T, E>
|
||||||
where
|
where
|
||||||
T: ~const Clone + ~const Drop,
|
T: ~const Clone + ~const Drop + ~const Destruct,
|
||||||
E: ~const Clone + ~const Drop,
|
E: ~const Clone + ~const Drop + ~const Destruct,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -121,11 +121,20 @@ impl Clean<Option<GenericBound>> for hir::GenericBound<'_> {
|
|||||||
hir::GenericBound::Trait(ref t, modifier) => {
|
hir::GenericBound::Trait(ref t, modifier) => {
|
||||||
// `T: ~const Drop` is not equivalent to `T: Drop`, and we don't currently document `~const` bounds
|
// `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.
|
// 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()
|
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
|
||||||
&& hir::TraitBoundModifier::MaybeConst == modifier
|
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;
|
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)
|
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> {
|
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
|
// `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.
|
// 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
|
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;
|
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);
|
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
|
||||||
Some(WherePredicate::BoundPredicate {
|
Some(WherePredicate::BoundPredicate {
|
||||||
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
|
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
#![feature(const_trait_impl, inline_const, negative_impls)]
|
#![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;
|
struct UnconstDrop;
|
||||||
|
|
||||||
@ -16,8 +18,8 @@ impl !Drop for NonDrop {}
|
|||||||
fn main() {
|
fn main() {
|
||||||
const {
|
const {
|
||||||
f(UnconstDrop);
|
f(UnconstDrop);
|
||||||
//~^ ERROR the trait bound `UnconstDrop: ~const Drop` is not satisfied
|
//~^ ERROR can't drop
|
||||||
f(NonDrop);
|
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
|
error[E0277]: can't drop `UnconstDrop` in const contexts
|
||||||
--> $DIR/const-block-const-bound.rs:18:11
|
--> $DIR/const-block-const-bound.rs:20:11
|
||||||
|
|
|
|
||||||
LL | f(UnconstDrop);
|
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
|
| 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`
|
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) {}
|
LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `f`
|
| ^^^^^^^^^^^^^^^ required by this bound in `f`
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | f(&UnconstDrop);
|
LL | f(&UnconstDrop);
|
||||||
@ -18,19 +19,20 @@ LL | f(&UnconstDrop);
|
|||||||
LL | f(&mut UnconstDrop);
|
LL | f(&mut UnconstDrop);
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonDrop: ~const Drop` is not satisfied
|
error[E0277]: can't drop `NonDrop` in const contexts
|
||||||
--> $DIR/const-block-const-bound.rs:20:11
|
--> $DIR/const-block-const-bound.rs:22:11
|
||||||
|
|
|
|
||||||
LL | f(NonDrop);
|
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
|
| 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`
|
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) {}
|
LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `f`
|
| ^^^^^^^^^^^^^^^ required by this bound in `f`
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | f(&NonDrop);
|
LL | f(&NonDrop);
|
||||||
|
@ -48,7 +48,7 @@ LL | const_eval_select((), 42, 0xDEADBEEF);
|
|||||||
note: required by a bound in `const_eval_select`
|
note: required by a bound in `const_eval_select`
|
||||||
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
--> $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`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
|
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`
|
note: required by a bound in `const_eval_select`
|
||||||
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
--> $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`
|
| ^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||||
|
|
||||||
error[E0631]: type mismatch in function arguments
|
error[E0631]: type mismatch in function arguments
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![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 {
|
match res {
|
||||||
Ok(t) => Some(t),
|
Ok(t) => Some(t),
|
||||||
Err(_e) => None,
|
Err(_e) => None,
|
||||||
@ -12,7 +14,11 @@ const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Drop {
|
|||||||
|
|
||||||
pub struct Foo<T>(T);
|
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, E>(res: Result<Foo<T>, Foo<E>>) -> Option<Foo<T>>
|
||||||
|
where
|
||||||
|
T: ~const Destruct,
|
||||||
|
E: ~const Destruct,
|
||||||
|
{
|
||||||
foo(res)
|
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
|
--> $DIR/const-drop-fail.rs:43:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
...
|
...
|
||||||
LL | NonTrivialDrop,
|
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`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:34:19
|
--> $DIR/const-drop-fail.rs:34:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | &NonTrivialDrop,
|
LL | &NonTrivialDrop,
|
||||||
@ -19,16 +20,16 @@ LL | &NonTrivialDrop,
|
|||||||
LL | &mut 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
|
--> $DIR/const-drop-fail.rs:45:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
...
|
...
|
||||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
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
|
--> $DIR/const-drop-fail.rs:45:5
|
||||||
|
|
|
|
||||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||||
@ -41,28 +42,24 @@ LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
|||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:34:19
|
--> $DIR/const-drop-fail.rs:34:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ 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
|
--> $DIR/const-drop-fail.rs:47:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
...
|
...
|
||||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
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>`
|
= note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||||
--> $DIR/const-drop-fail.rs:28:25
|
|
||||||
|
|
|
||||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
|
||||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:34:19
|
--> $DIR/const-drop-fail.rs:34:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![cfg_attr(precise, feature(const_precise_live_drops))]
|
#![cfg_attr(precise, feature(const_precise_live_drops))]
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::{Destruct, PhantomData};
|
||||||
|
|
||||||
struct NonTrivialDrop;
|
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 {
|
macro_rules! check_all {
|
||||||
($($exp:expr),*$(,)?) => {$(
|
($($exp:expr),*$(,)?) => {$(
|
||||||
@ -41,9 +41,9 @@ macro_rules! check_all {
|
|||||||
|
|
||||||
check_all! {
|
check_all! {
|
||||||
NonTrivialDrop,
|
NonTrivialDrop,
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR can't drop
|
||||||
ConstImplWithDropGlue(NonTrivialDrop),
|
ConstImplWithDropGlue(NonTrivialDrop),
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR can't drop
|
||||||
ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||||
//~^ ERROR the trait bound
|
//~^ 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
|
--> $DIR/const-drop-fail.rs:43:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
...
|
...
|
||||||
LL | NonTrivialDrop,
|
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`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:34:19
|
--> $DIR/const-drop-fail.rs:34:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | &NonTrivialDrop,
|
LL | &NonTrivialDrop,
|
||||||
@ -19,16 +20,16 @@ LL | &NonTrivialDrop,
|
|||||||
LL | &mut 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
|
--> $DIR/const-drop-fail.rs:45:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
...
|
...
|
||||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
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
|
--> $DIR/const-drop-fail.rs:45:5
|
||||||
|
|
|
|
||||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||||
@ -41,28 +42,24 @@ LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
|||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:34:19
|
--> $DIR/const-drop-fail.rs:34:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ 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
|
--> $DIR/const-drop-fail.rs:47:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
...
|
...
|
||||||
LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
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>`
|
= note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
|
||||||
--> $DIR/const-drop-fail.rs:28:25
|
|
||||||
|
|
|
||||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
|
|
||||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:34:19
|
--> $DIR/const-drop-fail.rs:34:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: ~const Drop>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
help: consider borrowing here
|
help: consider borrowing here
|
||||||
|
|
|
|
||||||
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
LL | &ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![cfg_attr(precise, feature(const_precise_live_drops))]
|
#![cfg_attr(precise, feature(const_precise_live_drops))]
|
||||||
|
|
||||||
|
use std::marker::Destruct;
|
||||||
|
|
||||||
struct S<'a>(&'a mut u8);
|
struct S<'a>(&'a mut u8);
|
||||||
|
|
||||||
impl<'a> const Drop for S<'a> {
|
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 {
|
const fn b() -> u8 {
|
||||||
let mut c = 0;
|
let mut c = 0;
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
// Regression test for #92111.
|
// 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
|
// check-pass
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
use std::marker::Destruct;
|
||||||
|
|
||||||
pub trait Tr {}
|
pub trait Tr {}
|
||||||
|
|
||||||
#[allow(drop_bounds)]
|
#[allow(drop_bounds)]
|
||||||
@ -21,7 +16,7 @@ pub struct S(i32);
|
|||||||
|
|
||||||
impl Tr for S {}
|
impl Tr for S {}
|
||||||
|
|
||||||
const fn a<T: ~const Drop>(t: T) {}
|
const fn a<T: ~const Destruct>(t: T) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
a(S(0));
|
a(S(0));
|
||||||
|
Loading…
Reference in New Issue
Block a user