about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2022-03-21 16:52:41 +1100
committerDeadbeef <ent3rm4n@gmail.com>2022-03-21 17:04:03 +1100
commit1f3ee7f32e1345e70f31adf1cb2d6f11d1d87c9a (patch)
tree5979e8a7dbd451f5c73d192b3b9529d52964e890
parent4df2a28aee55f73d4e898c931664b8087b06522d (diff)
downloadrust-1f3ee7f32e1345e70f31adf1cb2d6f11d1d87c9a.tar.gz
rust-1f3ee7f32e1345e70f31adf1cb2d6f11d1d87c9a.zip
Rename `~const Drop` to `~const Destruct`
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs16
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_lint/src/traits.rs4
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs16
-rw-r--r--compiler/rustc_middle/src/traits/select.rs4
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs32
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs60
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs8
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs2
-rw-r--r--library/alloc/src/alloc.rs8
-rw-r--r--library/alloc/src/borrow.rs1
-rw-r--r--library/alloc/src/boxed.rs28
-rw-r--r--library/core/src/bool.rs8
-rw-r--r--library/core/src/clone.rs5
-rw-r--r--library/core/src/intrinsics.rs8
-rw-r--r--library/core/src/marker.rs15
-rw-r--r--library/core/src/option.rs75
-rw-r--r--library/core/src/result.rs26
-rw-r--r--src/librustdoc/clean/mod.rs24
-rw-r--r--src/test/ui/consts/const-block-const-bound.rs8
-rw-r--r--src/test/ui/consts/const-block-const-bound.stderr26
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.stderr4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs6
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr33
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr33
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop.rs4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs11
32 files changed, 296 insertions, 192 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 4ea21b4d06d..1e02129855e 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -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;
             }
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 05944dd22bd..7c312e1b61d 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -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);
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index 5b6997bf0ee..81d308ee347 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -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.
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 45610fa77d3..36bbccf0a80 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -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>,
 }
 
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index e18f04d92ee..56d42706f67 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -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
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index 6ce9f5eea34..ea706053231 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -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)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 83ab761aa55..3124cc5dba8 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -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()))
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index c07cd86b4e2..48ca321b737 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -571,7 +571,7 @@ symbols! {
         deref_target,
         derive,
         derive_default_enum,
-        destructible,
+        destruct,
         destructuring_assignment,
         diagnostic,
         direct,
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 614a5e04809..390381752f9 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -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,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index d76bcf6807f..c0a283d2eda 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -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));
                 }
             }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 05479899f3a..3c980af5121 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -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 })
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index a1a8497859d..5d07139e87b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -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)) => {
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 295a91959eb..802a59abe5f 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -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,
     })
 }
 
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index bd7d721b5e1..44389ee47b0 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -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,
 ) {
diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs
index 8b13e36c4b3..27e5af4f1be 100644
--- a/library/alloc/src/borrow.rs
+++ b/library/alloc/src/borrow.rs
@@ -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>,
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 7dce3db0a47..b5f4c9a237b 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -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
     }
diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs
index d5119d0b7c3..a13593a539d 100644
--- a/library/core/src/bool.rs
+++ b/library/core/src/bool.rs
@@ -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 }
     }
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 1912694412b..cfdc51c71ee 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -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()
     }
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 1d457c2b7d5..22c6c1cd868 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -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)
 }
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 44d388fb7a3..6b9d6253e42 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -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.
 ///
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index bcba18a4a3e..acab8de8c70 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -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 {
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 9a243cbc3a2..afd0c857229 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -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 {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2c61b7468dc..1e3260ce9ae 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -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),
diff --git a/src/test/ui/consts/const-block-const-bound.rs b/src/test/ui/consts/const-block-const-bound.rs
index 1ccd0ee9370..42aa0216b87 100644
--- a/src/test/ui/consts/const-block-const-bound.rs
+++ b/src/test/ui/consts/const-block-const-bound.rs
@@ -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
     }
 }
diff --git a/src/test/ui/consts/const-block-const-bound.stderr b/src/test/ui/consts/const-block-const-bound.stderr
index b5f5694ba83..87ca771e54e 100644
--- a/src/test/ui/consts/const-block-const-bound.stderr
+++ b/src/test/ui/consts/const-block-const-bound.stderr
@@ -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);
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr
index 06a7a2f63cf..c03688d03b6 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.stderr
+++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr
@@ -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
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs
index a1cfee6b6e7..6fa35d2d97b 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs
@@ -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)
 }
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
index d88bcdc89ad..fedb1ffdea9 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
@@ -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),
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
index 49968b47dbe..001dd430a86 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
@@ -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
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
index d88bcdc89ad..fedb1ffdea9 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
@@ -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),
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
index 20b9d772147..f50e70939df 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop.rs
@@ -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;
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs
index da7147acdd7..96a3e386e6e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs
@@ -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));