about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2021-07-19 13:52:43 +0200
committerlcnr <rust@lcnr.de>2021-08-26 11:00:30 +0200
commitcaa975c89e343cb7e51f77c2710c8460ada50532 (patch)
tree7d5c957eb1d942180608f4ebe0bcfb648ec3cf11
parent031243898eaa138056ea7248fb37324ffaa561e1 (diff)
downloadrust-caa975c89e343cb7e51f77c2710c8460ada50532.tar.gz
rust-caa975c89e343cb7e51f77c2710c8460ada50532.zip
use `ty::Unevaluated` instead of def substs pair
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs5
-rw-r--r--compiler/rustc_middle/src/query/mod.rs5
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs2
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs8
-rw-r--r--compiler/rustc_privacy/src/lib.rs4
-rw-r--r--compiler/rustc_query_impl/src/keys.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs53
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs11
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs6
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_typeck/src/collect.rs7
19 files changed, 66 insertions, 86 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 155abf4ef83..7f890829e68 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -678,10 +678,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         a: ty::Unevaluated<'tcx>,
         b: ty::Unevaluated<'tcx>,
     ) -> bool {
-        let canonical = self.canonicalize_query(
-            ((a.def, a.substs(self.tcx)), (b.def, b.substs(self.tcx))),
-            &mut OriginalQueryValues::default(),
-        );
+        let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default());
         debug!("canonical consts: {:?}", &canonical.value);
 
         self.tcx.try_unify_abstract_consts(canonical.value)
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 737b1108f50..9b3de6710ec 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -303,12 +303,11 @@ rustc_queries! {
     }
 
     query try_unify_abstract_consts(key: (
-        (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
-        (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)
+        ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>
     )) -> bool {
         desc {
             |tcx| "trying to unify the generic constants {} and {}",
-            tcx.def_path_str(key.0.0.did), tcx.def_path_str(key.1.0.did)
+            tcx.def_path_str(key.0.def.did), tcx.def_path_str(key.1.def.did)
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 174c35dbc71..b1f6a612776 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -18,7 +18,7 @@ use super::ScalarInt;
 ///
 /// We check for all possible substs in `fn default_anon_const_substs`,
 /// so refer to that check for more info.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
 #[derive(Hash, HashStable)]
 pub struct Unevaluated<'tcx> {
     pub def: ty::WithOptConstParam<DefId>,
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 41c2447cfc5..1c4f24cdf39 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -252,8 +252,8 @@ impl FlagComputation {
             ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => {
                 self.add_substs(substs);
             }
-            ty::PredicateKind::ConstEvaluatable(_def_id, substs) => {
-                self.add_substs(substs);
+            ty::PredicateKind::ConstEvaluatable(uv) => {
+                self.add_unevaluated_const(uv);
             }
             ty::PredicateKind::ConstEquate(expected, found) => {
                 self.add_const(expected);
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index eccc1ebd805..b1ebe43c491 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -406,7 +406,7 @@ crate struct PredicateInner<'tcx> {
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(PredicateInner<'_>, 48);
+static_assert_size!(PredicateInner<'_>, 56);
 
 #[derive(Clone, Copy, Lift)]
 pub struct Predicate<'tcx> {
@@ -502,7 +502,7 @@ pub enum PredicateKind<'tcx> {
     Coerce(CoercePredicate<'tcx>),
 
     /// Constant initializer must evaluate successfully.
-    ConstEvaluatable(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
+    ConstEvaluatable(ty::Unevaluated<'tcx>),
 
     /// Constants must be equal. The first component is the const that is expected.
     ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5c3da507e14..230a39e639f 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2294,8 +2294,8 @@ define_print_and_forward_display! {
                 print_value_path(closure_def_id, &[]),
                 write("` implements the trait `{}`", kind))
             }
-            ty::PredicateKind::ConstEvaluatable(def, substs) => {
-                p!("the constant `", print_value_path(def.did, substs), "` can be evaluated")
+            ty::PredicateKind::ConstEvaluatable(uv) => {
+                p!("the constant `", print_value_path(uv.def.did, uv.substs_.map_or(&[], |x| x)), "` can be evaluated")
             }
             ty::PredicateKind::ConstEquate(c1, c2) => {
                 p!("the constant `", print(c1), "` equals `", print(c2), "`")
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index c978e1de38d..b64d507e0b8 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -579,7 +579,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
         (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
             if tcx.features().const_evaluatable_checked =>
         {
-            tcx.try_unify_abstract_consts(((au.def, au.substs(tcx)), (bu.def, bu.substs(tcx))))
+            tcx.try_unify_abstract_consts((au, bu))
         }
 
         // While this is slightly incorrect, it shouldn't matter for `min_const_generics`
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index dcdea8025fa..31088423efa 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -190,8 +190,8 @@ impl fmt::Debug for ty::PredicateKind<'tcx> {
             ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
                 write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
             }
-            ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
-                write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
+            ty::PredicateKind::ConstEvaluatable(uv) => {
+                write!(f, "ConstEvaluatable({:?}, {:?})", uv.def, uv.substs_)
             }
             ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
@@ -447,8 +447,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
             ty::PredicateKind::ObjectSafe(trait_def_id) => {
                 Some(ty::PredicateKind::ObjectSafe(trait_def_id))
             }
-            ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
-                tcx.lift(substs).map(|substs| ty::PredicateKind::ConstEvaluatable(def_id, substs))
+            ty::PredicateKind::ConstEvaluatable(uv) => {
+                tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv))
             }
             ty::PredicateKind::ConstEquate(c1, c2) => {
                 tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2))
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index fb223d8fa75..6fe68a0c17a 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -134,11 +134,11 @@ where
                 ty.visit_with(self)
             }
             ty::PredicateKind::RegionOutlives(..) => ControlFlow::CONTINUE,
-            ty::PredicateKind::ConstEvaluatable(defs, substs)
+            ty::PredicateKind::ConstEvaluatable(uv)
                 if self.def_id_visitor.tcx().features().const_evaluatable_checked =>
             {
                 let tcx = self.def_id_visitor.tcx();
-                if let Ok(Some(ct)) = AbstractConst::new(tcx, defs, substs) {
+                if let Ok(Some(ct)) = AbstractConst::new(tcx, uv) {
                     self.visit_abstract_const_expr(tcx, ct)?;
                 }
                 ControlFlow::CONTINUE
diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs
index 38ab26d66ac..8523737f8db 100644
--- a/compiler/rustc_query_impl/src/keys.rs
+++ b/compiler/rustc_query_impl/src/keys.rs
@@ -217,18 +217,13 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
     }
 }
 
-impl<'tcx> Key
-    for (
-        (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
-        (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
-    )
-{
+impl<'tcx> Key for (ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>) {
     #[inline(always)]
     fn query_crate_is_local(&self) -> bool {
-        (self.0).0.did.krate == LOCAL_CRATE
+        (self.0).def.did.krate == LOCAL_CRATE
     }
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        (self.0).0.did.default_span(tcx)
+        (self.0).def.did.default_span(tcx)
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 2cc74ca2abb..80c824565d2 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -19,7 +19,7 @@ use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind};
 use rustc_middle::ty::subst::{Subst, SubstsRef};
 use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
 use rustc_session::lint;
-use rustc_span::def_id::{DefId, LocalDefId};
+use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
 
 use std::cmp;
@@ -29,26 +29,20 @@ use std::ops::ControlFlow;
 /// Check if a given constant can be evaluated.
 pub fn is_const_evaluatable<'cx, 'tcx>(
     infcx: &InferCtxt<'cx, 'tcx>,
-    def: ty::WithOptConstParam<DefId>,
-    substs: SubstsRef<'tcx>,
+    uv: ty::Unevaluated<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     span: Span,
 ) -> Result<(), NotConstEvaluatable> {
-    debug!("is_const_evaluatable({:?}, {:?})", def, substs);
+    debug!("is_const_evaluatable({:?})", uv);
     if infcx.tcx.features().const_evaluatable_checked {
         let tcx = infcx.tcx;
-        match AbstractConst::new(tcx, def, substs)? {
+        match AbstractConst::new(tcx, uv)? {
             // We are looking at a generic abstract constant.
             Some(ct) => {
                 for pred in param_env.caller_bounds() {
                     match pred.kind().skip_binder() {
-                        ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => {
-                            if b_def == def && b_substs == substs {
-                                debug!("is_const_evaluatable: caller_bound ~~> ok");
-                                return Ok(());
-                            }
-
-                            if let Some(b_ct) = AbstractConst::new(tcx, b_def, b_substs)? {
+                        ty::PredicateKind::ConstEvaluatable(uv) => {
+                            if let Some(b_ct) = AbstractConst::new(tcx, uv)? {
                                 // Try to unify with each subtree in the AbstractConst to allow for
                                 // `N + 1` being const evaluatable even if theres only a `ConstEvaluatable`
                                 // predicate for `(N + 1) * 2`
@@ -134,7 +128,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
     }
 
     let future_compat_lint = || {
-        if let Some(local_def_id) = def.did.as_local() {
+        if let Some(local_def_id) = uv.def.did.as_local() {
             infcx.tcx.struct_span_lint_hir(
                 lint::builtin::CONST_EVALUATABLE_UNCHECKED,
                 infcx.tcx.hir().local_def_id_to_hir_id(local_def_id),
@@ -155,13 +149,12 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
     // and hopefully soon change this to an error.
     //
     // See #74595 for more details about this.
-    let concrete =
-        infcx.const_eval_resolve(param_env, ty::Unevaluated::new(def, substs), Some(span));
+    let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
 
-    if concrete.is_ok() && substs.has_param_types_or_consts(infcx.tcx) {
-        match infcx.tcx.def_kind(def.did) {
+    if concrete.is_ok() && uv.substs(infcx.tcx).has_param_types_or_consts(infcx.tcx) {
+        match infcx.tcx.def_kind(uv.def.did) {
             DefKind::AnonConst => {
-                let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(def);
+                let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
 
                 if mir_body.is_polymorphic {
                     future_compat_lint();
@@ -173,7 +166,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
 
     debug!(?concrete, "is_const_evaluatable");
     match concrete {
-        Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() {
+        Err(ErrorHandled::TooGeneric) => Err(match uv.has_infer_types_or_consts() {
             true => NotConstEvaluatable::MentionsInfer,
             false => NotConstEvaluatable::MentionsParam,
         }),
@@ -198,15 +191,14 @@ pub struct AbstractConst<'tcx> {
     pub substs: SubstsRef<'tcx>,
 }
 
-impl AbstractConst<'tcx> {
+impl<'tcx> AbstractConst<'tcx> {
     pub fn new(
         tcx: TyCtxt<'tcx>,
-        def: ty::WithOptConstParam<DefId>,
-        substs: SubstsRef<'tcx>,
+        uv: ty::Unevaluated<'tcx>,
     ) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
-        let inner = tcx.mir_abstract_const_opt_const_arg(def)?;
-        debug!("AbstractConst::new({:?}) = {:?}", def, inner);
-        Ok(inner.map(|inner| AbstractConst { inner, substs }))
+        let inner = tcx.mir_abstract_const_opt_const_arg(uv.def)?;
+        debug!("AbstractConst::new({:?}) = {:?}", uv, inner);
+        Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs(tcx) }))
     }
 
     pub fn from_const(
@@ -214,7 +206,7 @@ impl AbstractConst<'tcx> {
         ct: &ty::Const<'tcx>,
     ) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
         match ct.val {
-            ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.def, uv.substs(tcx)),
+            ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv),
             ty::ConstKind::Error(_) => Err(ErrorReported),
             _ => Ok(None),
         }
@@ -564,14 +556,11 @@ pub(super) fn mir_abstract_const<'tcx>(
 
 pub(super) fn try_unify_abstract_consts<'tcx>(
     tcx: TyCtxt<'tcx>,
-    ((a, a_substs), (b, b_substs)): (
-        (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
-        (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
-    ),
+    (a, b): (ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>),
 ) -> bool {
     (|| {
-        if let Some(a) = AbstractConst::new(tcx, a, a_substs)? {
-            if let Some(b) = AbstractConst::new(tcx, b, b_substs)? {
+        if let Some(a) = AbstractConst::new(tcx, a)? {
+            if let Some(b) = AbstractConst::new(tcx, b)? {
                 return Ok(try_unify(tcx, a, b));
             }
         }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 90b6ee5f5a6..6a7aafc334b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -811,10 +811,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 }
 
                 match obligation.predicate.kind().skip_binder() {
-                    ty::PredicateKind::ConstEvaluatable(def, _) => {
+                    ty::PredicateKind::ConstEvaluatable(uv) => {
                         let mut err =
                             self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
-                        let const_span = self.tcx.def_span(def.did);
+                        let const_span = self.tcx.def_span(uv.def.did);
                         match self.tcx.sess.source_map().span_to_snippet(const_span) {
                             Ok(snippet) => err.help(&format!(
                                 "try adding a `where` bound using this expression: `where [(); {}]:`",
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index edf2274ab54..a17921ace30 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -543,11 +543,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                     }
                 }
 
-                ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
+                ty::PredicateKind::ConstEvaluatable(uv) => {
                     match const_evaluatable::is_const_evaluatable(
                         self.selcx.infcx(),
-                        def_id,
-                        substs,
+                        uv,
                         obligation.param_env,
                         obligation.cause.span,
                     ) {
@@ -555,7 +554,9 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                         Err(NotConstEvaluatable::MentionsInfer) => {
                             pending_obligation.stalled_on.clear();
                             pending_obligation.stalled_on.extend(
-                                substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg),
+                                uv.substs(infcx.tcx)
+                                    .iter()
+                                    .filter_map(TyOrConstInferVar::maybe_from_generic_arg),
                             );
                             ProcessResult::Unchanged
                         }
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 9511b41147d..dd974e6fd4f 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -854,12 +854,12 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
         }
 
         fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
-            if let ty::PredicateKind::ConstEvaluatable(def, substs) = pred.kind().skip_binder() {
+            if let ty::PredicateKind::ConstEvaluatable(ct) = pred.kind().skip_binder() {
                 // FIXME(const_evaluatable_checked): We should probably deduplicate the logic for
                 // `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to
                 // take a `ty::Const` instead.
                 use rustc_middle::mir::abstract_const::Node;
-                if let Ok(Some(ct)) = AbstractConst::new(self.tcx, def, substs) {
+                if let Ok(Some(ct)) = AbstractConst::new(self.tcx, ct) {
                     const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() {
                         Node::Leaf(leaf) => {
                             let leaf = leaf.subst(self.tcx, ct.substs);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 1c4e7e6c589..6ddc3aad1b5 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -598,11 +598,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     }
                 }
 
-                ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
+                ty::PredicateKind::ConstEvaluatable(uv) => {
                     match const_evaluatable::is_const_evaluatable(
                         self.infcx,
-                        def_id,
-                        substs,
+                        uv,
                         obligation.param_env,
                         obligation.cause.span,
                     ) {
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 623215ec34e..75307f13563 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -132,8 +132,9 @@ pub fn predicate_obligations<'a, 'tcx>(
             wf.compute(a.into());
             wf.compute(b.into());
         }
-        ty::PredicateKind::ConstEvaluatable(def, substs) => {
-            let obligations = wf.nominal_obligations(def.did, substs);
+        ty::PredicateKind::ConstEvaluatable(uv) => {
+            let substs = uv.substs(wf.tcx());
+            let obligations = wf.nominal_obligations(uv.def.did, substs);
             wf.out.extend(obligations);
 
             for arg in substs.iter() {
@@ -442,8 +443,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                             let obligations = self.nominal_obligations(uv.def.did, substs);
                             self.out.extend(obligations);
 
-                            let predicate = ty::PredicateKind::ConstEvaluatable(uv.def, substs)
-                                .to_predicate(self.tcx());
+                            let predicate = ty::PredicateKind::ConstEvaluatable(
+                                ty::Unevaluated::new(uv.def, substs),
+                            )
+                            .to_predicate(self.tcx());
                             let cause = self.cause(traits::MiscObligation);
                             self.out.push(traits::Obligation::with_depth(
                                 cause,
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index c34dd705bef..fd150978f00 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -236,9 +236,9 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                     relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
                 }
                 (
-                    ty::PredicateKind::ConstEvaluatable(def_a, substs_a),
-                    ty::PredicateKind::ConstEvaluatable(def_b, substs_b),
-                ) => tcx.try_unify_abstract_consts(((def_a, substs_a), (def_b, substs_b))),
+                    ty::PredicateKind::ConstEvaluatable(a),
+                    ty::PredicateKind::ConstEvaluatable(b),
+                ) => tcx.try_unify_abstract_consts((a, b)),
                 (ty::PredicateKind::TypeOutlives(a), ty::PredicateKind::TypeOutlives(b)) => {
                     relator.relate(predicate.rebind(a.0), p.rebind(b.0)).is_ok()
                 }
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 057a15a4358..c76566806ed 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -541,10 +541,10 @@ fn check_type_defn<'tcx, F>(
                 fcx.register_predicate(traits::Obligation::new(
                     cause,
                     fcx.param_env,
-                    ty::PredicateKind::ConstEvaluatable(
+                    ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new(
                         ty::WithOptConstParam::unknown(discr_def_id.to_def_id()),
                         discr_substs,
-                    )
+                    ))
                     .to_predicate(tcx),
                 ));
             }
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index a5a402bc26a..df050fc9adc 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2355,11 +2355,8 @@ fn const_evaluatable_predicates_of<'tcx>(
             if let ty::ConstKind::Unevaluated(uv) = ct.val {
                 assert_eq!(uv.promoted, None);
                 let span = self.tcx.hir().span(c.hir_id);
-                self.preds.insert((
-                    ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs(self.tcx))
-                        .to_predicate(self.tcx),
-                    span,
-                ));
+                self.preds
+                    .insert((ty::PredicateKind::ConstEvaluatable(uv).to_predicate(self.tcx), span));
             }
         }