about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection')
-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
4 files changed, 70 insertions, 34 deletions
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)) => {