about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-03-21 03:36:22 +0000
committerbors <bors@rust-lang.org>2021-03-21 03:36:22 +0000
commitbbf07c0b4f210ced7bd2785ab554e0d805644235 (patch)
treebdaa957d4632277cb8db05193f7e9b5caf7ac5a8
parented4005da44b0dcbeaa35951ef994da82e156258f (diff)
parent69f6a195da5f7ed66bfde728f3feafdc621a6460 (diff)
downloadrust-bbf07c0b4f210ced7bd2785ab554e0d805644235.tar.gz
rust-bbf07c0b4f210ced7bd2785ab554e0d805644235.zip
Auto merge of #83333 - Dylan-DPC:rollup-0rdt6sz, r=Dylan-DPC
Rollup of 6 pull requests

Successful merges:

 - #82707 (const_evaluatable_checked: Stop eagerly erroring in `is_const_evaluatable`)
 - #83040 (extract `ConstKind::Unevaluated` into a struct)
 - #83280 (Fix pluralization in keyword docs)
 - #83289 (Move some tests to more reasonable directories - 5)
 - #83306 (Extend `proc_macro_back_compat` lint to `js-sys`)
 - #83327 (Extend comment in `UsedLocals::visit_lhs`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs4
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs34
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs7
-rw-r--r--compiler/rustc_middle/src/mir/abstract_const.rs17
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs10
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs12
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs19
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs10
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs24
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs10
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs4
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/mod.rs6
-rw-r--r--compiler/rustc_mir/src/interpret/operand.rs2
-rw-r--r--compiler/rustc_mir/src/monomorphize/collector.rs4
-rw-r--r--compiler/rustc_mir/src/monomorphize/polymorphize.rs6
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/qualifs.rs2
-rw-r--r--compiler/rustc_mir/src/transform/const_prop.rs6
-rw-r--r--compiler/rustc_mir/src/transform/inline.rs2
-rw-r--r--compiler/rustc_mir/src/transform/promote_consts.rs8
-rw-r--r--compiler/rustc_mir/src/transform/required_consts.rs2
-rw-r--r--compiler/rustc_mir/src/transform/simplify.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs114
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs67
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs41
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs2
-rw-r--r--compiler/rustc_typeck/src/collect.rs5
-rw-r--r--library/std/src/keyword_docs.rs4
-rw-r--r--src/librustdoc/clean/utils.rs2
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff4
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff4
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff4
-rw-r--r--src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff4
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff4
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff4
-rw-r--r--src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff4
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff4
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff4
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff4
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff4
-rw-r--r--src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir8
-rw-r--r--src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff4
-rw-r--r--src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff4
-rw-r--r--src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff4
-rw-r--r--src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff4
-rw-r--r--src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff12
-rw-r--r--src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir4
-rw-r--r--src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir4
-rw-r--r--src/test/ui/associated-types/issue-23208.rs (renamed from src/test/ui/issues/issue-23208.rs)0
-rw-r--r--src/test/ui/associated-types/issue-31597.rs (renamed from src/test/ui/issues/issue-31597.rs)0
-rw-r--r--src/test/ui/binding/shadow.rs (renamed from src/test/ui/shadow.rs)0
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr36
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr6
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs17
-rw-r--r--src/test/ui/const_evaluatable/needs_where_clause.stderr6
-rw-r--r--src/test/ui/const_evaluatable/no_where_clause.stderr6
-rw-r--r--src/test/ui/consts/issue-52060.rs (renamed from src/test/ui/issues/issue-52060.rs)0
-rw-r--r--src/test/ui/consts/issue-52060.stderr (renamed from src/test/ui/issues/issue-52060.stderr)0
-rw-r--r--src/test/ui/consts/mir_check_nonconst.rs (renamed from src/test/ui/mir_check_nonconst.rs)0
-rw-r--r--src/test/ui/consts/mir_check_nonconst.stderr (renamed from src/test/ui/mir_check_nonconst.stderr)0
-rw-r--r--src/test/ui/generator/issue-45729-unsafe-in-generator.rs (renamed from src/test/ui/issues/issue-45729-unsafe-in-generator.rs)0
-rw-r--r--src/test/ui/generator/issue-45729-unsafe-in-generator.stderr (renamed from src/test/ui/issues/issue-45729-unsafe-in-generator.stderr)0
-rw-r--r--src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs (renamed from src/test/ui/impl-trait-in-bindings-issue-73003.rs)0
-rw-r--r--src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr (renamed from src/test/ui/impl-trait-in-bindings-issue-73003.stderr)0
-rw-r--r--src/test/ui/impl-trait/impl-trait-in-bindings.rs (renamed from src/test/ui/impl-trait-in-bindings.rs)0
-rw-r--r--src/test/ui/impl-trait/impl-trait-in-bindings.stderr (renamed from src/test/ui/impl-trait-in-bindings.stderr)0
-rw-r--r--src/test/ui/lint/fn_must_use.rs (renamed from src/test/ui/fn_must_use.rs)0
-rw-r--r--src/test/ui/lint/fn_must_use.stderr (renamed from src/test/ui/fn_must_use.stderr)0
-rw-r--r--src/test/ui/macros/concat-rpass.rs (renamed from src/test/ui/concat-rpass.rs)0
-rw-r--r--src/test/ui/parser/issue-48508-aux.rs (renamed from src/test/ui/issues/issue-48508-aux.rs)0
-rw-r--r--src/test/ui/parser/issue-48508.rs (renamed from src/test/ui/issues/issue-48508.rs)0
-rw-r--r--src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.rs (renamed from src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs)0
-rw-r--r--src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.stderr (renamed from src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr)0
-rw-r--r--src/test/ui/pattern/issue-10392.rs (renamed from src/test/ui/issues/issue-10392.rs)0
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs9
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr43
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout13
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.40/src/lib.rs7
-rw-r--r--src/test/ui/resolve/no-implicit-prelude.rs (renamed from src/test/ui/no-implicit-prelude.rs)0
-rw-r--r--src/test/ui/resolve/no-implicit-prelude.stderr (renamed from src/test/ui/no-implicit-prelude.stderr)0
-rw-r--r--src/test/ui/structs-enums/issue-1701.rs (renamed from src/test/ui/issues/issue-1701.rs)0
-rw-r--r--src/test/ui/traits/issue-78372.rs (renamed from src/test/ui/issues/issue-78372.rs)0
-rw-r--r--src/test/ui/traits/issue-78372.stderr (renamed from src/test/ui/issues/issue-78372.stderr)0
-rw-r--r--src/test/ui/typeck/issue-65611.rs (renamed from src/test/ui/issues/issue-65611.rs)0
-rw-r--r--src/test/ui/typeck/issue-65611.stderr (renamed from src/test/ui/issues/issue-65611.stderr)0
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs8
-rw-r--r--src/tools/tidy/src/ui_tests.rs4
94 files changed, 436 insertions, 295 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index 9d93370b7d0..f4cbfb6967f 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -45,9 +45,9 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
         };
         match const_.val {
             ConstKind::Value(_) => {}
-            ConstKind::Unevaluated(def, ref substs, promoted) => {
+            ConstKind::Unevaluated(unevaluated) => {
                 if let Err(err) =
-                    fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
+                    fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None)
                 {
                     all_constants_ok = false;
                     match err {
@@ -122,14 +122,14 @@ pub(crate) fn codegen_constant<'tcx>(
     };
     let const_val = match const_.val {
         ConstKind::Value(const_val) => const_val,
-        ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => {
+        ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => {
             assert!(substs.is_empty());
             assert!(promoted.is_none());
 
             return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx);
         }
-        ConstKind::Unevaluated(def, ref substs, promoted) => {
-            match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) {
+        ConstKind::Unevaluated(unevaluated) => {
+            match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
                 Ok(const_val) => const_val,
                 Err(_) => {
                     span_bug!(constant.span, "erroneous constant not captured by required_consts");
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index aa41acc3578..fa8a53e60b1 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -30,10 +30,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::ConstantKind::Val(val, _) => return Ok(val),
         };
         match ct.val {
-            ty::ConstKind::Unevaluated(def, substs, promoted) => self
+            ty::ConstKind::Unevaluated(ct) => self
                 .cx
                 .tcx()
-                .const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None)
+                .const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None)
                 .map_err(|err| {
                     self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
                     err
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index cb41bc81225..1ea26b4eab4 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -739,9 +739,8 @@ fn ident_name_compatibility_hack(
 
                 let time_macros_impl =
                     macro_name == sym::impl_macros && matches_prefix("time-macros-impl", "lib.rs");
-                if time_macros_impl
-                    || (macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs"))
-                {
+                let js_sys = macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs");
+                if time_macros_impl || js_sys {
                     let snippet = source_map.span_to_snippet(orig_span);
                     if snippet.as_deref() == Ok("$name") {
                         if time_macros_impl {
@@ -754,8 +753,35 @@ fn ident_name_compatibility_hack(
                                 "the `time-macros-impl` crate will stop compiling in futures version of Rust. \
                                 Please update to the latest version of the `time` crate to avoid breakage".to_string())
                             );
+                            return Some((*ident, *is_raw));
+                        }
+                        if js_sys {
+                            if let Some(c) = path
+                                .components()
+                                .flat_map(|c| c.as_os_str().to_str())
+                                .find(|c| c.starts_with("js-sys"))
+                            {
+                                let mut version = c.trim_start_matches("js-sys-").split(".");
+                                if version.next() == Some("0")
+                                    && version.next() == Some("3")
+                                    && version
+                                        .next()
+                                        .and_then(|c| c.parse::<u32>().ok())
+                                        .map_or(false, |v| v < 40)
+                                {
+                                    rustc.sess.buffer_lint_with_diagnostic(
+                                        &PROC_MACRO_BACK_COMPAT,
+                                        orig_span,
+                                        ast::CRATE_NODE_ID,
+                                        "using an old version of `js-sys`",
+                                        BuiltinLintDiagnostics::ProcMacroBackCompat(
+                                        "older versions of the `js-sys` crate will stop compiling in future versions of Rust; \
+                                        please update to `js-sys` v0.3.40 or above".to_string())
+                                    );
+                                    return Some((*ident, *is_raw));
+                                }
+                            }
                         }
-                        return Some((*ident, *is_raw));
                     }
                 }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 3df58cb7857..7b18f4d0ff6 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -18,7 +18,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
 use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
-use rustc_middle::mir;
 use rustc_middle::mir::interpret::EvalToConstValueResult;
 use rustc_middle::traits::select;
 use rustc_middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
@@ -1499,9 +1498,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn const_eval_resolve(
         &self,
         param_env: ty::ParamEnv<'tcx>,
-        def: ty::WithOptConstParam<DefId>,
-        substs: SubstsRef<'tcx>,
-        promoted: Option<mir::Promoted>,
+        ty::Unevaluated { def, substs, promoted }: ty::Unevaluated<'tcx>,
         span: Option<Span>,
     ) -> EvalToConstValueResult<'tcx> {
         let mut original_values = OriginalQueryValues::default();
@@ -1510,7 +1507,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let (param_env, substs) = canonical.value;
         // The return value is the evaluated value which doesn't contain any reference to inference
         // variables, thus we don't need to substitute back the original values.
-        self.tcx.const_eval_resolve(param_env, def, substs, promoted, span)
+        self.tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, span)
     }
 
     /// If `typ` is a type variable of some kind, resolve it one level
diff --git a/compiler/rustc_middle/src/mir/abstract_const.rs b/compiler/rustc_middle/src/mir/abstract_const.rs
index b85f1e6e5de..776a777b1bd 100644
--- a/compiler/rustc_middle/src/mir/abstract_const.rs
+++ b/compiler/rustc_middle/src/mir/abstract_const.rs
@@ -18,3 +18,20 @@ pub enum Node<'tcx> {
     UnaryOp(mir::UnOp, NodeId),
     FunctionCall(NodeId, &'tcx [NodeId]),
 }
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
+pub enum NotConstEvaluatable {
+    Error(rustc_errors::ErrorReported),
+    MentionsInfer,
+    MentionsParam,
+}
+
+impl From<rustc_errors::ErrorReported> for NotConstEvaluatable {
+    fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable {
+        NotConstEvaluatable::Error(e)
+    }
+}
+
+TrivialTypeFoldableAndLiftImpls! {
+    NotConstEvaluatable,
+}
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 3e7b93b32a6..fa7c0670e8c 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -1,7 +1,7 @@
 use super::{ErrorHandled, EvalToConstValueResult, GlobalId};
 
 use crate::mir;
-use crate::ty::subst::{InternalSubsts, SubstsRef};
+use crate::ty::subst::InternalSubsts;
 use crate::ty::{self, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_span::Span;
@@ -35,14 +35,12 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn const_eval_resolve(
         self,
         param_env: ty::ParamEnv<'tcx>,
-        def: ty::WithOptConstParam<DefId>,
-        substs: SubstsRef<'tcx>,
-        promoted: Option<mir::Promoted>,
+        ct: ty::Unevaluated<'tcx>,
         span: Option<Span>,
     ) -> EvalToConstValueResult<'tcx> {
-        match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) {
+        match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
             Ok(Some(instance)) => {
-                let cid = GlobalId { instance, promoted };
+                let cid = GlobalId { instance, promoted: ct.promoted };
                 self.const_eval_global_id(param_env, cid, span)
             }
             Ok(None) => Err(ErrorHandled::TooGeneric),
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 0bd0a701fb2..90b82020551 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -9,7 +9,7 @@ pub mod specialization_graph;
 mod structural_impls;
 
 use crate::infer::canonical::Canonical;
-use crate::mir::interpret::ErrorHandled;
+use crate::mir::abstract_const::NotConstEvaluatable;
 use crate::ty::subst::SubstsRef;
 use crate::ty::{self, AdtKind, Ty, TyCtxt};
 
@@ -398,7 +398,7 @@ pub enum SelectionError<'tcx> {
         ty::error::TypeError<'tcx>,
     ),
     TraitNotObjectSafe(DefId),
-    ConstEvalFailure(ErrorHandled),
+    NotConstEvaluatable(NotConstEvaluatable),
     Overflow,
 }
 
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 622f8e8ff6c..779d6c90f97 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -98,18 +98,18 @@ impl<'tcx> Const<'tcx> {
                 let name = tcx.hir().name(hir_id);
                 ty::ConstKind::Param(ty::ParamConst::new(index, name))
             }
-            _ => ty::ConstKind::Unevaluated(
-                def.to_global(),
-                InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
-                None,
-            ),
+            _ => ty::ConstKind::Unevaluated(ty::Unevaluated {
+                def: def.to_global(),
+                substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
+                promoted: None,
+            }),
         };
 
         tcx.mk_const(ty::Const { val, ty })
     }
 
-    #[inline]
     /// Interns the given value as a constant.
+    #[inline]
     pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
         tcx.mk_const(Self { val: ConstKind::Value(val), ty })
     }
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 43e22ce8f87..875d8d00a93 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -12,10 +12,18 @@ use rustc_macros::HashStable;
 use rustc_target::abi::Size;
 
 use super::ScalarInt;
+/// An unevaluated, potentially generic, constant.
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
+#[derive(Hash, HashStable)]
+pub struct Unevaluated<'tcx> {
+    pub def: ty::WithOptConstParam<DefId>,
+    pub substs: SubstsRef<'tcx>,
+    pub promoted: Option<Promoted>,
+}
 
 /// Represents a constant in Rust.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
-#[derive(HashStable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
+#[derive(Hash, HashStable)]
 pub enum ConstKind<'tcx> {
     /// A const generic parameter.
     Param(ty::ParamConst),
@@ -31,7 +39,7 @@ pub enum ConstKind<'tcx> {
 
     /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
     /// variants when the code is monomorphic enough for that.
-    Unevaluated(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>, Option<Promoted>),
+    Unevaluated(Unevaluated<'tcx>),
 
     /// Used to hold computed value.
     Value(ConstValue<'tcx>),
@@ -102,7 +110,7 @@ impl<'tcx> ConstKind<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ParamEnv<'tcx>,
     ) -> Option<Result<ConstValue<'tcx>, ErrorReported>> {
-        if let ConstKind::Unevaluated(def, substs, promoted) = self {
+        if let ConstKind::Unevaluated(Unevaluated { def, substs, promoted }) = self {
             use crate::mir::interpret::ErrorHandled;
 
             // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
@@ -132,7 +140,8 @@ impl<'tcx> ConstKind<'tcx> {
             let (param_env, substs) = param_env_and_substs.into_parts();
             // try to resolve e.g. associated constants to their definition on an impl, and then
             // evaluate the const.
-            match tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
+            match tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, None)
+            {
                 // NOTE(eddyb) `val` contains no lifetimes/types/consts,
                 // and we use the original type, so nothing from `substs`
                 // (which may be identity substs, see above),
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 6ecd1ebf370..d6dc81c5b78 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -270,10 +270,7 @@ impl FlagComputation {
     fn add_const(&mut self, c: &ty::Const<'_>) {
         self.add_ty(c.ty);
         match c.val {
-            ty::ConstKind::Unevaluated(_, substs, _) => {
-                self.add_substs(substs);
-                self.add_flags(TypeFlags::HAS_CT_PROJECTION);
-            }
+            ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated),
             ty::ConstKind::Infer(infer) => {
                 self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
                 match infer {
@@ -297,6 +294,11 @@ impl FlagComputation {
         }
     }
 
+    fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'tcx>) {
+        self.add_substs(ct.substs);
+        self.add_flags(TypeFlags::HAS_CT_PROJECTION);
+    }
+
     fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
         self.add_substs(projection.substs);
         self.add_ty(projection.ty);
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 5bbf7b35d3d..e6b4739d0a2 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -55,7 +55,7 @@ pub use rustc_type_ir::*;
 
 pub use self::binding::BindingMode;
 pub use self::binding::BindingMode::*;
-pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, ValTree};
+pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, Unevaluated, ValTree};
 pub use self::context::{
     tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
     CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 7946d170064..3b72cc011d6 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -915,7 +915,7 @@ pub trait PrettyPrinter<'tcx>:
         }
 
         match ct.val {
-            ty::ConstKind::Unevaluated(def, substs, promoted) => {
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
                 if let Some(promoted) = promoted {
                     p!(print_value_path(def.did, substs));
                     p!(write("::{:?}", promoted));
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index b41bf70e88e..c936c30f456 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -531,24 +531,26 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
             check_const_value_eq(relation, a_val, b_val, a, b)?
         }
 
-        (
-            ty::ConstKind::Unevaluated(a_def, a_substs, None),
-            ty::ConstKind::Unevaluated(b_def, b_substs, None),
-        ) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => {
-            tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
+        (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
+            if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() =>
+        {
+            tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs)))
         }
 
         // While this is slightly incorrect, it shouldn't matter for `min_const_generics`
         // and is the better alternative to waiting until `const_evaluatable_checked` can
         // be stabilized.
-        (
-            ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted),
-            ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted),
-        ) if a_def == b_def && a_promoted == b_promoted => {
+        (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
+            if au.def == bu.def && au.promoted == bu.promoted =>
+        {
             let substs =
-                relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
+                relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?;
             return Ok(tcx.mk_const(ty::Const {
-                val: ty::ConstKind::Unevaluated(a_def, substs, a_promoted),
+                val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+                    def: au.def,
+                    substs,
+                    promoted: au.promoted,
+                }),
                 ty: a.ty,
             }));
         }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 0ca94a9f180..2da23b331e0 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -1031,8 +1031,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
         match self {
             ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)),
             ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)),
-            ty::ConstKind::Unevaluated(did, substs, promoted) => {
-                ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted)
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
+                ty::ConstKind::Unevaluated(ty::Unevaluated {
+                    def,
+                    substs: substs.fold_with(folder),
+                    promoted,
+                })
             }
             ty::ConstKind::Value(_)
             | ty::ConstKind::Bound(..)
@@ -1045,7 +1049,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
         match *self {
             ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
             ty::ConstKind::Param(p) => p.visit_with(visitor),
-            ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor),
+            ty::ConstKind::Unevaluated(ct) => ct.substs.visit_with(visitor),
             ty::ConstKind::Value(_)
             | ty::ConstKind::Bound(..)
             | ty::ConstKind::Placeholder(_)
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index bb7fc661d2d..c2fe5f1ef3f 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -195,8 +195,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
                 | ty::ConstKind::Value(_)
                 | ty::ConstKind::Error(_) => {}
 
-                ty::ConstKind::Unevaluated(_, substs, _) => {
-                    stack.extend(substs.iter().rev());
+                ty::ConstKind::Unevaluated(ct) => {
+                    stack.extend(ct.substs.iter().rev());
                 }
             }
         }
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
index cce1549cb29..aaa2bf4ff1b 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
@@ -316,14 +316,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
             let tcx = self.tcx();
             let maybe_uneval = match constant.literal {
                 ConstantKind::Ty(ct) => match ct.val {
-                    ty::ConstKind::Unevaluated(def, substs, promoted) => {
-                        Some((def, substs, promoted))
-                    }
+                    ty::ConstKind::Unevaluated(uv) => Some(uv),
                     _ => None,
                 },
                 _ => None,
             };
-            if let Some((def, substs, promoted)) = maybe_uneval {
+            if let Some(ty::Unevaluated { def, substs, promoted }) = maybe_uneval {
                 if let Some(promoted) = promoted {
                     let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
                                      promoted: &Body<'tcx>,
diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs
index 28933493a21..c70b57e631a 100644
--- a/compiler/rustc_mir/src/interpret/operand.rs
+++ b/compiler/rustc_mir/src/interpret/operand.rs
@@ -560,7 +560,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         match val.val {
             ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
             ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)),
-            ty::ConstKind::Unevaluated(def, substs, promoted) => {
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
                 let instance = self.resolve(def, substs)?;
                 Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into())
             }
diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs
index 911224d8c1f..e48640e1bb9 100644
--- a/compiler/rustc_mir/src/monomorphize/collector.rs
+++ b/compiler/rustc_mir/src/monomorphize/collector.rs
@@ -646,8 +646,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
 
         match substituted_constant.val {
             ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output),
-            ty::ConstKind::Unevaluated(def, substs, promoted) => {
-                match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
+            ty::ConstKind::Unevaluated(unevaluated) => {
+                match self.tcx.const_eval_resolve(param_env, unevaluated, None) {
                     Ok(val) => collect_const_value(self.tcx, val, self.output),
                     Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
                     Err(ErrorHandled::TooGeneric) => span_bug!(
diff --git a/compiler/rustc_mir/src/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs
index 05b0e3a7dab..30e758c7fdf 100644
--- a/compiler/rustc_mir/src/monomorphize/polymorphize.rs
+++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs
@@ -299,7 +299,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
                 self.unused_parameters.clear(param.index);
                 ControlFlow::CONTINUE
             }
-            ty::ConstKind::Unevaluated(def, _, Some(p))
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)})
                 // Avoid considering `T` unused when constants are of the form:
                 //   `<Self as Foo<T>>::foo::promoted[p]`
                 if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self =>
@@ -310,10 +310,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
                 self.visit_body(&promoted[p]);
                 ControlFlow::CONTINUE
             }
-            ty::ConstKind::Unevaluated(def, unevaluated_substs, None)
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None })
                 if self.tcx.def_kind(def.did) == DefKind::AnonConst =>
             {
-                self.visit_child_body(def.did, unevaluated_substs);
+                self.visit_child_body(def.did, substs);
                 ControlFlow::CONTINUE
             }
             _ => c.super_visit_with(self),
diff --git a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs
index 748f65cba22..36644ab3c59 100644
--- a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs
@@ -247,7 +247,7 @@ where
 
     // Check the qualifs of the value of `const` items.
     if let Some(ct) = constant.literal.const_for_ty() {
-        if let ty::ConstKind::Unevaluated(def, _, promoted) = ct.val {
+        if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val {
             assert!(promoted.is_none());
             // Don't peek inside trait associated constants.
             if cx.tcx.trait_of_item(def.did).is_none() {
diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs
index cc8669d9705..7706316c965 100644
--- a/compiler/rustc_mir/src/transform/const_prop.rs
+++ b/compiler/rustc_mir/src/transform/const_prop.rs
@@ -491,7 +491,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     let lint_only = match c.literal {
                         ConstantKind::Ty(ct) => match ct.val {
                             // Promoteds must lint and not error as the user didn't ask for them
-                            ConstKind::Unevaluated(_, _, Some(_)) => true,
+                            ConstKind::Unevaluated(ty::Unevaluated {
+                                def: _,
+                                substs: _,
+                                promoted: Some(_),
+                            }) => true,
                             // Out of backwards compatibility we cannot report hard errors in unused
                             // generic functions using associated constants of the generic parameters.
                             _ => c.literal.needs_subst(),
diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs
index 12fdbd6582e..b6f80763bc8 100644
--- a/compiler/rustc_mir/src/transform/inline.rs
+++ b/compiler/rustc_mir/src/transform/inline.rs
@@ -630,7 +630,7 @@ impl Inliner<'tcx> {
                 caller_body.required_consts.extend(
                     callee_body.required_consts.iter().copied().filter(|&ct| {
                         match ct.literal.const_for_ty() {
-                            Some(ct) => matches!(ct.val, ConstKind::Unevaluated(_, _, _)),
+                            Some(ct) => matches!(ct.val, ConstKind::Unevaluated(_)),
                             None => true,
                         }
                     }),
diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs
index 7db790cf32b..c5a03f3a045 100644
--- a/compiler/rustc_mir/src/transform/promote_consts.rs
+++ b/compiler/rustc_mir/src/transform/promote_consts.rs
@@ -1001,17 +1001,17 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                     literal: tcx
                         .mk_const(ty::Const {
                             ty,
-                            val: ty::ConstKind::Unevaluated(
+                            val: ty::ConstKind::Unevaluated(ty::Unevaluated {
                                 def,
-                                InternalSubsts::for_item(tcx, def.did, |param, _| {
+                                substs: InternalSubsts::for_item(tcx, def.did, |param, _| {
                                     if let ty::GenericParamDefKind::Lifetime = param.kind {
                                         tcx.lifetimes.re_erased.into()
                                     } else {
                                         tcx.mk_param_from_def(param)
                                     }
                                 }),
-                                Some(promoted_id),
-                            ),
+                                promoted: Some(promoted_id),
+                            }),
                         })
                         .into(),
                 }))
diff --git a/compiler/rustc_mir/src/transform/required_consts.rs b/compiler/rustc_mir/src/transform/required_consts.rs
index 2b518bd3a48..8b64ad65ab3 100644
--- a/compiler/rustc_mir/src/transform/required_consts.rs
+++ b/compiler/rustc_mir/src/transform/required_consts.rs
@@ -15,7 +15,7 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
 impl<'a, 'tcx> Visitor<'tcx> for RequiredConstsVisitor<'a, 'tcx> {
     fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
         if let Some(ct) = constant.literal.const_for_ty() {
-            if let ConstKind::Unevaluated(_, _, _) = ct.val {
+            if let ConstKind::Unevaluated(_) = ct.val {
                 self.required_consts.push(*constant);
             }
         }
diff --git a/compiler/rustc_mir/src/transform/simplify.rs b/compiler/rustc_mir/src/transform/simplify.rs
index d2314a9ba15..3b074f9132f 100644
--- a/compiler/rustc_mir/src/transform/simplify.rs
+++ b/compiler/rustc_mir/src/transform/simplify.rs
@@ -422,7 +422,9 @@ impl UsedLocals<'tcx> {
             // A use, not a definition.
             self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), location);
         } else {
-            // A definition. Although, it still might use other locals for indexing.
+            // A definition. The base local itself is not visited, so this occurrence is not counted
+            // toward its use count. There might be other locals still, used in an indexing
+            // projection.
             self.super_projection(
                 place.as_ref(),
                 PlaceContext::MutatingUse(MutatingUseContext::Projection),
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 200a5fc1043..9abee283160 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -707,11 +707,11 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> {
                                 // and not the beginning of discriminants (which is always `0`)
                                 let substs = InternalSubsts::identity_for_item(self.tcx(), did);
                                 let lhs = mk_const(self.tcx().mk_const(ty::Const {
-                                    val: ty::ConstKind::Unevaluated(
-                                        ty::WithOptConstParam::unknown(did),
+                                    val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+                                        def: ty::WithOptConstParam::unknown(did),
                                         substs,
-                                        None,
-                                    ),
+                                        promoted: None,
+                                    }),
                                     ty: var_ty,
                                 }));
                                 let bin =
@@ -905,11 +905,11 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> {
                 debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
                 ExprKind::Literal {
                     literal: self.tcx.mk_const(ty::Const {
-                        val: ty::ConstKind::Unevaluated(
-                            ty::WithOptConstParam::unknown(def_id),
+                        val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+                            def: ty::WithOptConstParam::unknown(def_id),
                             substs,
-                            None,
-                        ),
+                            promoted: None,
+                        }),
                         ty: self.typeck_results().node_type(expr.hir_id),
                     }),
                     user_ty,
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 6510c9464e1..0d71fc57e39 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -803,12 +803,10 @@ impl AutoTraitFinder<'tcx> {
                 }
                 ty::PredicateKind::ConstEquate(c1, c2) => {
                     let evaluate = |c: &'tcx ty::Const<'tcx>| {
-                        if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
+                        if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
                             match select.infcx().const_eval_resolve(
                                 obligation.param_env,
-                                def,
-                                substs,
-                                promoted,
+                                unevaluated,
                                 Some(obligation.cause.span),
                             ) {
                                 Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)),
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 670527fb3f0..ac987a9f7b3 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -13,7 +13,7 @@ use rustc_hir::def::DefKind;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::InferCtxt;
-use rustc_middle::mir::abstract_const::{Node, NodeId};
+use rustc_middle::mir::abstract_const::{Node, NodeId, NotConstEvaluatable};
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind};
 use rustc_middle::ty::subst::{Subst, SubstsRef};
@@ -32,7 +32,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
     substs: SubstsRef<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     span: Span,
-) -> Result<(), ErrorHandled> {
+) -> Result<(), NotConstEvaluatable> {
     debug!("is_const_evaluatable({:?}, {:?})", def, substs);
     if infcx.tcx.features().const_evaluatable_checked {
         let tcx = infcx.tcx;
@@ -103,29 +103,10 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
 
                 match failure_kind {
                     FailureKind::MentionsInfer => {
-                        return Err(ErrorHandled::TooGeneric);
+                        return Err(NotConstEvaluatable::MentionsInfer);
                     }
                     FailureKind::MentionsParam => {
-                        // FIXME(const_evaluatable_checked): Better error message.
-                        let mut err =
-                            infcx.tcx.sess.struct_span_err(span, "unconstrained generic constant");
-                        let const_span = tcx.def_span(def.did);
-                        // FIXME(const_evaluatable_checked): Update this suggestion once
-                        // explicit const evaluatable bounds are implemented.
-                        if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(const_span)
-                        {
-                            err.span_help(
-                                tcx.def_span(def.did),
-                                &format!("try adding a `where` bound using this expression: `where [u8; {}]: Sized`", snippet),
-                            );
-                        } else {
-                            err.span_help(
-                                const_span,
-                                "consider adding a `where` bound for this expression",
-                            );
-                        }
-                        err.emit();
-                        return Err(ErrorHandled::Reported(ErrorReported));
+                        return Err(NotConstEvaluatable::MentionsParam);
                     }
                     FailureKind::Concrete => {
                         // Dealt with below by the same code which handles this
@@ -163,7 +144,11 @@ 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, def, substs, None, Some(span));
+    let concrete = infcx.const_eval_resolve(
+        param_env,
+        ty::Unevaluated { def, substs, promoted: None },
+        Some(span),
+    );
 
     if concrete.is_ok() && substs.has_param_types_or_consts() {
         match infcx.tcx.def_kind(def.did) {
@@ -180,34 +165,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
 
     debug!(?concrete, "is_const_evaluatable");
     match concrete {
-        Err(ErrorHandled::TooGeneric) if !substs.has_infer_types_or_consts() => {
-            // FIXME(const_evaluatable_checked): We really should move
-            // emitting this error message to fulfill instead. For
-            // now this is easier.
-            //
-            // This is not a problem without `const_evaluatable_checked` as
-            // all `ConstEvaluatable` predicates have to be fulfilled for compilation
-            // to succeed.
-            //
-            // @lcnr: We already emit an error for things like
-            // `fn test<const N: usize>() -> [0 - N]` eagerly here,
-            // so until we fix this I don't really care.
-
-            let mut err = infcx
-                .tcx
-                .sess
-                .struct_span_err(span, "constant expression depends on a generic parameter");
-            // FIXME(const_generics): we should suggest to the user how they can resolve this
-            // issue. However, this is currently not actually possible
-            // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083).
-            //
-            // Note that with `feature(const_evaluatable_checked)` this case should not
-            // be reachable.
-            err.note("this may fail depending on what value the parameter takes");
-            err.emit();
-            Err(ErrorHandled::Reported(ErrorReported))
+        Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() {
+            true => NotConstEvaluatable::MentionsInfer,
+            false => NotConstEvaluatable::MentionsParam,
+        }),
+        Err(ErrorHandled::Linted) => {
+            infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
+            Err(NotConstEvaluatable::Error(ErrorReported))
         }
-        c => c.map(drop),
+        Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
+        Ok(_) => Ok(()),
     }
 }
 
@@ -239,7 +206,9 @@ impl AbstractConst<'tcx> {
         ct: &ty::Const<'tcx>,
     ) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
         match ct.val {
-            ty::ConstKind::Unevaluated(def, substs, None) => AbstractConst::new(tcx, def, substs),
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => {
+                AbstractConst::new(tcx, def, substs)
+            }
             ty::ConstKind::Error(_) => Err(ErrorReported),
             _ => Ok(None),
         }
@@ -532,22 +501,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
             if let Some(next) = self.build_terminator(block.terminator())? {
                 block = &self.body.basic_blocks()[next];
             } else {
-                assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
+                break;
+            }
+        }
+
+        assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
+        for n in self.nodes.iter() {
+            if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n.node {
                 // `AbstractConst`s should not contain any promoteds as they require references which
                 // are not allowed.
-                assert!(!self.nodes.iter().any(|n| matches!(
-                    n.node,
-                    Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(_, _, Some(_)), ty: _ })
-                )));
-
-                self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
-                if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
-                    self.error(Some(unused.span), "dead code")?;
-                }
-
-                return Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node)));
+                assert_eq!(ct.promoted, None);
             }
         }
+
+        self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
+        if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
+            self.error(Some(unused.span), "dead code")?;
+        }
+
+        Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node)))
     }
 }
 
@@ -673,10 +645,16 @@ pub(super) fn try_unify<'tcx>(
                 // we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
                 // means that we only allow inference variables if they are equal.
                 (ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => a_val == b_val,
-                (
-                    ty::ConstKind::Unevaluated(a_def, a_substs, None),
-                    ty::ConstKind::Unevaluated(b_def, b_substs, None),
-                ) => a_def == b_def && a_substs == b_substs,
+                // We expand generic anonymous constants at the start of this function, so this
+                // branch should only be taking when dealing with associated constants, at
+                // which point directly comparing them seems like the desired behavior.
+                //
+                // FIXME(const_evaluatable_checked): This isn't actually the case.
+                // We also take this branch for concrete anonymous constants and
+                // expand generic anonymous constants with concrete substs.
+                (ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => {
+                    a_uv == b_uv
+                }
                 // FIXME(const_evaluatable_checked): We may want to either actually try
                 // to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
                 // this, for now we just return false here.
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 a3faf4cb7d4..060e4e36dfe 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2,10 +2,10 @@ pub mod on_unimplemented;
 pub mod suggestions;
 
 use super::{
-    ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode,
-    MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
-    OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
-    PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
+    EvaluationResult, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
+    Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective,
+    OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation,
+    SelectionContext, SelectionError, TraitNotObjectSafe,
 };
 
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
@@ -17,7 +17,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::Node;
-use rustc_middle::mir::interpret::ErrorHandled;
+use rustc_middle::mir::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::{
@@ -738,24 +738,59 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 let violations = self.tcx.object_safety_violations(did);
                 report_object_safety_error(self.tcx, span, did, violations)
             }
-            ConstEvalFailure(ErrorHandled::TooGeneric) => {
-                bug!("too generic should have been handled in `is_const_evaluatable`");
+
+            SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsInfer) => {
+                bug!(
+                    "MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`"
+                )
+            }
+            SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => {
+                if !self.tcx.features().const_evaluatable_checked {
+                    let mut err = self.tcx.sess.struct_span_err(
+                        span,
+                        "constant expression depends on a generic parameter",
+                    );
+                    // FIXME(const_generics): we should suggest to the user how they can resolve this
+                    // issue. However, this is currently not actually possible
+                    // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083).
+                    //
+                    // Note that with `feature(const_evaluatable_checked)` this case should not
+                    // be reachable.
+                    err.note("this may fail depending on what value the parameter takes");
+                    err.emit();
+                    return;
+                }
+
+                match obligation.predicate.kind().skip_binder() {
+                    ty::PredicateKind::ConstEvaluatable(def, _) => {
+                        let mut err =
+                            self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
+                        let const_span = self.tcx.def_span(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 [(); {}]:`",
+                                snippet
+                            )),
+                            _ => err.help("consider adding a `where` bound using this expression"),
+                        };
+                        err
+                    }
+                    _ => {
+                        span_bug!(
+                            span,
+                            "unexpected non-ConstEvaluatable predicate, this should not be reachable"
+                        )
+                    }
+                }
             }
+
             // Already reported in the query.
-            ConstEvalFailure(ErrorHandled::Reported(ErrorReported)) => {
+            SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(ErrorReported)) => {
                 // FIXME(eddyb) remove this once `ErrorReported` becomes a proof token.
                 self.tcx.sess.delay_span_bug(span, "`ErrorReported` without an error");
                 return;
             }
 
-            // Already reported in the query, but only as a lint.
-            // This shouldn't actually happen for constants used in types, modulo
-            // bugs. The `delay_span_bug` here ensures it won't be ignored.
-            ConstEvalFailure(ErrorHandled::Linted) => {
-                self.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
-                return;
-            }
-
             Overflow => {
                 bug!("overflow should be handled before the `report_selection_error` path");
             }
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 7d451fc2341..79f65669479 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -3,7 +3,8 @@ use rustc_data_structures::obligation_forest::ProcessResult;
 use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
 use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
 use rustc_errors::ErrorReported;
-use rustc_infer::traits::{TraitEngine, TraitEngineExt as _, TraitObligation};
+use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation};
+use rustc_middle::mir::abstract_const::NotConstEvaluatable;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::subst::SubstsRef;
@@ -18,7 +19,7 @@ use super::wf;
 use super::CodeAmbiguity;
 use super::CodeProjectionError;
 use super::CodeSelectionError;
-use super::{ConstEvalFailure, Unimplemented};
+use super::Unimplemented;
 use super::{FulfillmentError, FulfillmentErrorCode};
 use super::{ObligationCause, PredicateObligation};
 
@@ -498,14 +499,19 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                         obligation.cause.span,
                     ) {
                         Ok(()) => ProcessResult::Changed(vec![]),
-                        Err(ErrorHandled::TooGeneric) => {
+                        Err(NotConstEvaluatable::MentionsInfer) => {
                             pending_obligation.stalled_on.clear();
                             pending_obligation.stalled_on.extend(
                                 substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg),
                             );
                             ProcessResult::Unchanged
                         }
-                        Err(e) => ProcessResult::Error(CodeSelectionError(ConstEvalFailure(e))),
+                        Err(
+                            e @ NotConstEvaluatable::MentionsParam
+                            | e @ NotConstEvaluatable::Error(_),
+                        ) => ProcessResult::Error(CodeSelectionError(
+                            SelectionError::NotConstEvaluatable(e),
+                        )),
                     }
                 }
 
@@ -516,15 +522,13 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                         // if the constants depend on generic parameters.
                         //
                         // Let's just see where this breaks :shrug:
-                        if let (
-                            ty::ConstKind::Unevaluated(a_def, a_substs, None),
-                            ty::ConstKind::Unevaluated(b_def, b_substs, None),
-                        ) = (c1.val, c2.val)
+                        if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
+                            (c1.val, c2.val)
                         {
                             if self
                                 .selcx
                                 .tcx()
-                                .try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
+                                .try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs)))
                             {
                                 return ProcessResult::Changed(vec![]);
                             }
@@ -534,18 +538,17 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                     let stalled_on = &mut pending_obligation.stalled_on;
 
                     let mut evaluate = |c: &'tcx Const<'tcx>| {
-                        if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
+                        if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
                             match self.selcx.infcx().const_eval_resolve(
                                 obligation.param_env,
-                                def,
-                                substs,
-                                promoted,
+                                unevaluated,
                                 Some(obligation.cause.span),
                             ) {
                                 Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)),
                                 Err(ErrorHandled::TooGeneric) => {
                                     stalled_on.extend(
-                                        substs
+                                        unevaluated
+                                            .substs
                                             .iter()
                                             .filter_map(TyOrConstInferVar::maybe_from_generic_arg),
                                     );
@@ -576,11 +579,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                             }
                         }
                         (Err(ErrorHandled::Reported(ErrorReported)), _)
-                        | (_, Err(ErrorHandled::Reported(ErrorReported))) => {
-                            ProcessResult::Error(CodeSelectionError(ConstEvalFailure(
-                                ErrorHandled::Reported(ErrorReported),
-                            )))
-                        }
+                        | (_, Err(ErrorHandled::Reported(ErrorReported))) => ProcessResult::Error(
+                            CodeSelectionError(SelectionError::NotConstEvaluatable(
+                                NotConstEvaluatable::Error(ErrorReported),
+                            )),
+                        ),
                         (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => {
                             span_bug!(
                                 obligation.cause.span(self.selcx.tcx()),
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 45b5aff40a6..bc0f0d6dea5 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -34,6 +34,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::Constness;
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
+use rustc_middle::mir::abstract_const::NotConstEvaluatable;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::fast_reject;
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -547,7 +548,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         obligation.cause.span,
                     ) {
                         Ok(()) => Ok(EvaluatedToOk),
-                        Err(ErrorHandled::TooGeneric) => Ok(EvaluatedToAmbig),
+                        Err(NotConstEvaluatable::MentionsInfer) => Ok(EvaluatedToAmbig),
+                        Err(NotConstEvaluatable::MentionsParam) => Ok(EvaluatedToErr),
                         Err(_) => Ok(EvaluatedToErr),
                     }
                 }
@@ -556,13 +558,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts");
 
                     let evaluate = |c: &'tcx ty::Const<'tcx>| {
-                        if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
+                        if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
                             self.infcx
                                 .const_eval_resolve(
                                     obligation.param_env,
-                                    def,
-                                    substs,
-                                    promoted,
+                                    unevaluated,
                                     Some(obligation.cause.span),
                                 )
                                 .map(|val| ty::Const::from_value(self.tcx(), val, c.ty))
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index e6ef9b137d8..aee128dec7d 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -430,7 +430,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
 
                 GenericArgKind::Const(constant) => {
                     match constant.val {
-                        ty::ConstKind::Unevaluated(def, substs, promoted) => {
+                        ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
                             assert!(promoted.is_none());
 
                             let obligations = self.nominal_obligations(def.did, substs);
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index e5136355ca9..162fccc6020 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2212,10 +2212,11 @@ fn const_evaluatable_predicates_of<'tcx>(
         fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
             let def_id = self.tcx.hir().local_def_id(c.hir_id);
             let ct = ty::Const::from_anon_const(self.tcx, def_id);
-            if let ty::ConstKind::Unevaluated(def, substs, None) = ct.val {
+            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(def, substs).to_predicate(self.tcx),
+                    ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs).to_predicate(self.tcx),
                     span,
                 ));
             }
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 383eaf2e3a2..e64cbc18bf7 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1031,8 +1031,8 @@ mod mod_keyword {}
 /// };
 /// ```
 ///
-/// For more information on the `move` keyword, see the [closure]'s section
-/// of the Rust book or the [threads] section
+/// For more information on the `move` keyword, see the [closures][closure] section
+/// of the Rust book or the [threads] section.
 ///
 /// [closure]: ../book/ch13-01-closures.html
 /// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 8b5f5b66c45..6f283d501a4 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -296,7 +296,7 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
 
 crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
     match n.val {
-        ty::ConstKind::Unevaluated(def, _, promoted) => {
+        ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => {
             let mut s = if let Some(def) = def.as_local() {
                 let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did);
                 print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id))
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
index 5ba76c4f0bd..4e990dd6b70 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -22,7 +22,7 @@
 -                                          // + ty: &i32
 -                                          // + val: Value(Scalar(alloc0))
 +                                          // + ty: &[&i32; 1]
-+                                          // + val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, [], Some(promoted[0]))
++                                          // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
 -                                          // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
 -                                          // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) }
@@ -30,7 +30,7 @@
 -         _3 = [move _4];                  // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
 -         _2 = &_3;                        // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
 +                                          // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:35
-+                                          // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, [], Some(promoted[0])) }
++                                          // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
 +         _2 = &(*_6);                     // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
           _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
 -         StorageDead(_4);                 // scope 0 at $DIR/const-promotion-extern-static.rs:9:34: 9:35
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index 1565cc7d5e7..0a9a3f3c2c5 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -24,7 +24,7 @@
 -                                          // + ty: *const i32
 -                                          // + val: Value(Scalar(alloc2))
 +                                          // + ty: &[&i32; 1]
-+                                          // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0]))
++                                          // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
 -                                          // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
 -                                          // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) }
@@ -32,7 +32,7 @@
 -         _3 = [move _4];                  // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
 -         _2 = &_3;                        // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
 +                                          // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:46
-+                                          // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0])) }
++                                          // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
 +         _2 = &(*_6);                     // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
           _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
 -         StorageDead(_4);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:45: 13:46
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
index 8c10b3518d8..baa8988f152 100644
--- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
@@ -28,10 +28,10 @@
           _9 = const main::promoted[0];    // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
                                            // ty::Const
                                            // + ty: &[i32; 3]
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
-                                           // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _3 = _9;                         // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
           _2 = &raw const (*_3);           // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
           _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
index 8c10b3518d8..baa8988f152 100644
--- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
@@ -28,10 +28,10 @@
           _9 = const main::promoted[0];    // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
                                            // ty::Const
                                            // + ty: &[i32; 3]
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
-                                           // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _3 = _9;                         // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
           _2 = &raw const (*_3);           // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
           _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
index 60346458646..8ba11df7e0e 100644
--- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
@@ -19,10 +19,10 @@
           _3 = const FOO;                  // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
                                            // ty::Const
                                            // + ty: &i32
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, [], None)
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None })
                                            // mir::Constant
                                            // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
-                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, [], None) }
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None }) }
           _2 = &raw const (*_3);           // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
           _1 = move _2 as usize (Misc);    // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39
           StorageDead(_2);                 // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:38: 7:39
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
index 4fd1b8b2276..56683d7ef03 100644
--- a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
@@ -14,10 +14,10 @@
           _4 = const main::promoted[0];    // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
                                            // ty::Const
                                            // + ty: &i32
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $DIR/ref_deref.rs:5:6: 5:10
-                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _2 = _4;                         // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
 -         _1 = (*_2);                      // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
 +         _1 = const 4_i32;                // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
index e7ebfee7f3e..e1c8085b31b 100644
--- a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
+++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
@@ -17,10 +17,10 @@
 +         _4 = const main::promoted[0];    // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
 +                                          // ty::Const
 +                                          // + ty: &i32
-+                                          // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0]))
++                                          // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
 +                                          // mir::Constant
 +                                          // + span: $DIR/ref_deref.rs:5:6: 5:10
-+                                          // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
++                                          // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
 +         _2 = &(*_4);                     // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
           _1 = (*_2);                      // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
 -         StorageDead(_3);                 // scope 0 at $DIR/ref_deref.rs:5:10: 5:11
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
index 812c7c97718..cce4831b6fe 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
@@ -14,10 +14,10 @@
           _4 = const main::promoted[0];    // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
                                            // ty::Const
                                            // + ty: &(i32, i32)
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $DIR/ref_deref_project.rs:5:6: 5:17
-                                           // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _2 = &((*_4).1: i32);            // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
           _1 = (*_2);                      // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
           StorageDead(_2);                 // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
index 588c291bcc3..93ba9de8202 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
+++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
@@ -17,10 +17,10 @@
 +         _4 = const main::promoted[0];    // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
 +                                          // ty::Const
 +                                          // + ty: &(i32, i32)
-+                                          // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0]))
++                                          // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
 +                                          // mir::Constant
 +                                          // + span: $DIR/ref_deref_project.rs:5:6: 5:17
-+                                          // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
++                                          // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
 +         _2 = &((*_4).1: i32);            // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
           _1 = (*_2);                      // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
 -         StorageDead(_3);                 // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
index 240cc8e2311..20f93f874c5 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -21,10 +21,10 @@
           _9 = const main::promoted[0];    // scope 0 at $DIR/slice_len.rs:5:6: 5:19
                                            // ty::Const
                                            // + ty: &[u32; 3]
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $DIR/slice_len.rs:5:6: 5:19
-                                           // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:5:6: 5:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:5:6: 5:19
           _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
index 240cc8e2311..20f93f874c5 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -21,10 +21,10 @@
           _9 = const main::promoted[0];    // scope 0 at $DIR/slice_len.rs:5:6: 5:19
                                            // ty::Const
                                            // + ty: &[u32; 3]
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $DIR/slice_len.rs:5:6: 5:19
-                                           // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:5:6: 5:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:5:6: 5:19
           _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
index b9fe84fcd04..0b5dc2b20fc 100644
--- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
@@ -35,10 +35,10 @@ fn bar() -> bool {
         _10 = const bar::promoted[1];    // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
                                          // ty::Const
                                          // + ty: &i32
-                                         // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[1]))
+                                         // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) })
                                          // mir::Constant
                                          // + span: $DIR/inline-retag.rs:12:7: 12:9
-                                         // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[1])) }
+                                         // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) }) }
         Retag(_10);                      // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
         _4 = &(*_10);                    // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
         Retag(_4);                       // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
@@ -49,10 +49,10 @@ fn bar() -> bool {
         _9 = const bar::promoted[0];     // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
                                          // ty::Const
                                          // + ty: &i32
-                                         // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[0]))
+                                         // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                          // mir::Constant
                                          // + span: $DIR/inline-retag.rs:12:11: 12:14
-                                         // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[0])) }
+                                         // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
         Retag(_9);                       // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
         _7 = &(*_9);                     // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
         Retag(_7);                       // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
index f6e6614bb6e..1ba56016776 100644
--- a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
+++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
@@ -63,10 +63,10 @@
           _20 = const main::promoted[0];   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
                                            // ty::Const
                                            // + ty: &i32
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _8 = _20;                        // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_6.0: &i32) = move _7;          // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_6.1: &i32) = move _8;          // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
index f6e6614bb6e..1ba56016776 100644
--- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
+++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
@@ -63,10 +63,10 @@
           _20 = const main::promoted[0];   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
                                            // ty::Const
                                            // + ty: &i32
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _8 = _20;                        // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_6.0: &i32) = move _7;          // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_6.1: &i32) = move _8;          // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
index bd24522271b..5ae26b73a65 100644
--- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
+++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
@@ -84,10 +84,10 @@
           _28 = const main::promoted[0];   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
                                            // ty::Const
                                            // + ty: &i32
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _11 = _28;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_9.0: &i32) = move _10;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_9.1: &i32) = move _11;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
index bd24522271b..5ae26b73a65 100644
--- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
+++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
@@ -84,10 +84,10 @@
           _28 = const main::promoted[0];   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
                                            // ty::Const
                                            // + ty: &i32
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
           _11 = _28;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_9.0: &i32) = move _10;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
           (_9.1: &i32) = move _11;         // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
index 7da2ff02006..83650d837b0 100644
--- a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
@@ -47,10 +47,10 @@
           _19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
                                            // ty::Const
                                            // + ty: &i32
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) })
                                            // mir::Constant
                                            // + span: $DIR/lower_intrinsics.rs:70:42: 70:44
-                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2])) }
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) }) }
           _7 = &(*_19);                    // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
           _6 = &(*_7);                     // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
 -         _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
@@ -71,10 +71,10 @@
           _18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
                                            // ty::Const
                                            // + ty: &()
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) })
                                            // mir::Constant
                                            // + span: $DIR/lower_intrinsics.rs:71:42: 71:45
-                                           // + literal: Const { ty: &(), val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1])) }
+                                           // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) }) }
           _11 = &(*_18);                   // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
           _10 = &(*_11);                   // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
 -         _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
@@ -95,10 +95,10 @@
           _17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
                                            // ty::Const
                                            // + ty: &E
-                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0]))
+                                           // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) })
                                            // mir::Constant
                                            // + span: $DIR/lower_intrinsics.rs:72:42: 72:47
-                                           // + literal: Const { ty: &E, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0])) }
+                                           // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) }) }
           _15 = &(*_17);                   // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
           _14 = &(*_15);                   // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
 -         _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
index 2332e5beafe..242138754c5 100644
--- a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
+++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
@@ -54,10 +54,10 @@ fn full_tested_match() -> () {
         _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
                                          // ty::Const
                                          // + ty: &std::option::Option<i32>
-                                         // + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, [], Some(promoted[0]))
+                                         // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                          // mir::Constant
                                          // + span: $DIR/match_false_edges.rs:16:14: 16:15
-                                         // + literal: Const { ty: &std::option::Option<i32>, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, [], Some(promoted[0])) }
+                                         // + literal: Const { ty: &std::option::Option<i32>, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
         _6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
         _4 = &shallow _2;                // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
         StorageLive(_7);                 // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
index 8c7d79262b2..d25f98db9f6 100644
--- a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
@@ -149,10 +149,10 @@ fn main() -> () {
         _27 = const main::promoted[0];   // scope 7 at $DIR/retag.rs:47:21: 47:23
                                          // ty::Const
                                          // + ty: &i32
-                                         // + val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+                                         // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
                                          // mir::Constant
                                          // + span: $DIR/retag.rs:47:21: 47:23
-                                         // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+                                         // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
         Retag(_27);                      // scope 7 at $DIR/retag.rs:47:21: 47:23
         _23 = &(*_27);                   // scope 7 at $DIR/retag.rs:47:21: 47:23
         Retag(_23);                      // scope 7 at $DIR/retag.rs:47:21: 47:23
diff --git a/src/test/ui/issues/issue-23208.rs b/src/test/ui/associated-types/issue-23208.rs
index fd4ffe5d6e1..fd4ffe5d6e1 100644
--- a/src/test/ui/issues/issue-23208.rs
+++ b/src/test/ui/associated-types/issue-23208.rs
diff --git a/src/test/ui/issues/issue-31597.rs b/src/test/ui/associated-types/issue-31597.rs
index 2872be6d6c8..2872be6d6c8 100644
--- a/src/test/ui/issues/issue-31597.rs
+++ b/src/test/ui/associated-types/issue-31597.rs
diff --git a/src/test/ui/shadow.rs b/src/test/ui/binding/shadow.rs
index 2495c8f47e7..2495c8f47e7 100644
--- a/src/test/ui/shadow.rs
+++ b/src/test/ui/binding/shadow.rs
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
index 1beb5315d10..84b2665d5bf 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
@@ -3,48 +3,52 @@ error: unconstrained generic constant
    |
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
-  --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
+   | 
+  ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
    |
 LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |          ---------------------------- required by this bound in `test1`
+   |
+   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 
 error: unconstrained generic constant
   --> $DIR/cross_crate_predicate.rs:7:13
    |
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
-  --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
+   | 
+  ::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                           ---------------------------- required by this bound in `test1`
+   |
+   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 
 error: unconstrained generic constant
   --> $DIR/cross_crate_predicate.rs:7:13
    |
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
-  --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
+   | 
+  ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
    |
 LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |          ---------------------------- required by this bound in `test1`
+   |
+   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 
 error: unconstrained generic constant
   --> $DIR/cross_crate_predicate.rs:7:13
    |
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
-  --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
+   | 
+  ::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                           ---------------------------- required by this bound in `test1`
+   |
+   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr
index 8cdc9b57750..7c11a47b2f0 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr
@@ -4,11 +4,7 @@ error: unconstrained generic constant
 LL |     [0; size_of::<Foo<T>>()]
    |         ^^^^^^^^^^^^^^^^^^^
    |
-help: try adding a `where` bound using this expression: `where [u8; size_of::<Foo<T>>()]: Sized`
-  --> $DIR/different-fn.rs:10:9
-   |
-LL |     [0; size_of::<Foo<T>>()]
-   |         ^^^^^^^^^^^^^^^^^^^
+   = help: try adding a `where` bound using this expression: `where [(); size_of::<Foo<T>>()]:`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs b/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs
new file mode 100644
index 00000000000..92a410afcb1
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![feature(const_generics)]
+#![feature(const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+// This test is a repro for #82279. It checks that we don't error
+// when calling is_const_evaluatable on `std::mem::size_of::<T>()`
+// when looking for candidates that may prove `T: Foo` in `foo`
+
+trait Foo {}
+
+#[allow(dead_code)]
+fn foo<T: Foo>() {}
+
+impl<T> Foo for T where [(); std::mem::size_of::<T>()]:  {}
+
+fn main() {}
diff --git a/src/test/ui/const_evaluatable/needs_where_clause.stderr b/src/test/ui/const_evaluatable/needs_where_clause.stderr
index 945105d1a2d..7b41e39b7d7 100644
--- a/src/test/ui/const_evaluatable/needs_where_clause.stderr
+++ b/src/test/ui/const_evaluatable/needs_where_clause.stderr
@@ -4,11 +4,7 @@ error: unconstrained generic constant
 LL |   b: [f32; complex_maths::<T>(N)],
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: try adding a `where` bound using this expression: `where [u8; complex_maths::<T>(N)]: Sized`
-  --> $DIR/needs_where_clause.rs:11:12
-   |
-LL |   b: [f32; complex_maths::<T>(N)],
-   |            ^^^^^^^^^^^^^^^^^^^^^
+   = help: try adding a `where` bound using this expression: `where [(); complex_maths::<T>(N)]:`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const_evaluatable/no_where_clause.stderr b/src/test/ui/const_evaluatable/no_where_clause.stderr
index 84a65f0d1d2..3e5c2f5cad1 100644
--- a/src/test/ui/const_evaluatable/no_where_clause.stderr
+++ b/src/test/ui/const_evaluatable/no_where_clause.stderr
@@ -4,11 +4,7 @@ error: unconstrained generic constant
 LL |   b: [f32; complex_maths(N)],
    |      ^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: try adding a `where` bound using this expression: `where [u8; complex_maths(N)]: Sized`
-  --> $DIR/no_where_clause.rs:10:12
-   |
-LL |   b: [f32; complex_maths(N)],
-   |            ^^^^^^^^^^^^^^^^
+   = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-52060.rs b/src/test/ui/consts/issue-52060.rs
index 13b914c0331..13b914c0331 100644
--- a/src/test/ui/issues/issue-52060.rs
+++ b/src/test/ui/consts/issue-52060.rs
diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/consts/issue-52060.stderr
index 95e5f2a8282..95e5f2a8282 100644
--- a/src/test/ui/issues/issue-52060.stderr
+++ b/src/test/ui/consts/issue-52060.stderr
diff --git a/src/test/ui/mir_check_nonconst.rs b/src/test/ui/consts/mir_check_nonconst.rs
index b8ec0c3c449..b8ec0c3c449 100644
--- a/src/test/ui/mir_check_nonconst.rs
+++ b/src/test/ui/consts/mir_check_nonconst.rs
diff --git a/src/test/ui/mir_check_nonconst.stderr b/src/test/ui/consts/mir_check_nonconst.stderr
index 30f68ba4372..30f68ba4372 100644
--- a/src/test/ui/mir_check_nonconst.stderr
+++ b/src/test/ui/consts/mir_check_nonconst.stderr
diff --git a/src/test/ui/issues/issue-45729-unsafe-in-generator.rs b/src/test/ui/generator/issue-45729-unsafe-in-generator.rs
index 638a1994bb5..638a1994bb5 100644
--- a/src/test/ui/issues/issue-45729-unsafe-in-generator.rs
+++ b/src/test/ui/generator/issue-45729-unsafe-in-generator.rs
diff --git a/src/test/ui/issues/issue-45729-unsafe-in-generator.stderr b/src/test/ui/generator/issue-45729-unsafe-in-generator.stderr
index 2aab6807aaa..2aab6807aaa 100644
--- a/src/test/ui/issues/issue-45729-unsafe-in-generator.stderr
+++ b/src/test/ui/generator/issue-45729-unsafe-in-generator.stderr
diff --git a/src/test/ui/impl-trait-in-bindings-issue-73003.rs b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs
index fd8fe5f48df..fd8fe5f48df 100644
--- a/src/test/ui/impl-trait-in-bindings-issue-73003.rs
+++ b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs
diff --git a/src/test/ui/impl-trait-in-bindings-issue-73003.stderr b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr
index 715671c8add..715671c8add 100644
--- a/src/test/ui/impl-trait-in-bindings-issue-73003.stderr
+++ b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr
diff --git a/src/test/ui/impl-trait-in-bindings.rs b/src/test/ui/impl-trait/impl-trait-in-bindings.rs
index c7fae45d5ca..c7fae45d5ca 100644
--- a/src/test/ui/impl-trait-in-bindings.rs
+++ b/src/test/ui/impl-trait/impl-trait-in-bindings.rs
diff --git a/src/test/ui/impl-trait-in-bindings.stderr b/src/test/ui/impl-trait/impl-trait-in-bindings.stderr
index bf739d4722f..bf739d4722f 100644
--- a/src/test/ui/impl-trait-in-bindings.stderr
+++ b/src/test/ui/impl-trait/impl-trait-in-bindings.stderr
diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/lint/fn_must_use.rs
index b4e9da0fc84..b4e9da0fc84 100644
--- a/src/test/ui/fn_must_use.rs
+++ b/src/test/ui/lint/fn_must_use.rs
diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr
index d6b1cf3ae1f..d6b1cf3ae1f 100644
--- a/src/test/ui/fn_must_use.stderr
+++ b/src/test/ui/lint/fn_must_use.stderr
diff --git a/src/test/ui/concat-rpass.rs b/src/test/ui/macros/concat-rpass.rs
index 0c30a39d6a2..0c30a39d6a2 100644
--- a/src/test/ui/concat-rpass.rs
+++ b/src/test/ui/macros/concat-rpass.rs
diff --git a/src/test/ui/issues/issue-48508-aux.rs b/src/test/ui/parser/issue-48508-aux.rs
index ebdc70a04df..ebdc70a04df 100644
--- a/src/test/ui/issues/issue-48508-aux.rs
+++ b/src/test/ui/parser/issue-48508-aux.rs
diff --git a/src/test/ui/issues/issue-48508.rs b/src/test/ui/parser/issue-48508.rs
index 8dc9351260e..8dc9351260e 100644
--- a/src/test/ui/issues/issue-48508.rs
+++ b/src/test/ui/parser/issue-48508.rs
diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.rs
index 3c49a5a9752..3c49a5a9752 100644
--- a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs
+++ b/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.rs
diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.stderr
index ef365a61643..ef365a61643 100644
--- a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr
+++ b/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.stderr
diff --git a/src/test/ui/issues/issue-10392.rs b/src/test/ui/pattern/issue-10392.rs
index 926fa94800e..926fa94800e 100644
--- a/src/test/ui/issues/issue-10392.rs
+++ b/src/test/ui/pattern/issue-10392.rs
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
index d9687490cad..2b742771d6f 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
@@ -43,7 +43,8 @@ mod with_version {
     struct Foo;
     impl_macros!(Foo); //~  WARN using an old version
                        //~| WARN this was previously
-    arrays!(Foo);
+    arrays!(Foo); //~  WARN using an old version
+                  //~| WARN this was previously
     other!(Foo);
 }
 
@@ -77,5 +78,11 @@ mod actori_web_version_test {
     tuple_from_req!(Foo);
 }
 
+mod with_good_js_sys_version {
+    include!("js-sys-0.3.40/src/lib.rs");
+    struct Foo;
+    arrays!(Foo);
+}
+
 
 fn main() {}
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
index e2b680f8d27..effcd68cf96 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
@@ -31,13 +31,29 @@ LL |     impl_macros!(Foo);
    = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage
    = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
+warning: using an old version of `js-sys`
+  --> $DIR/js-sys-0.3.17/src/lib.rs:5:32
+   |
+LL |         #[my_macro] struct Two($name);
+   |                                ^^^^^
+   | 
+  ::: $DIR/group-compat-hack.rs:46:5
+   |
+LL |     arrays!(Foo);
+   |     ------------- in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `js-sys` crate will stop compiling in future versions of Rust; please update to `js-sys` v0.3.40 or above
+   = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
 warning: using an old version of `actix-web`
   --> $DIR/actix-web/src/extract.rs:5:34
    |
 LL |         #[my_macro] struct Three($T);
    |                                  ^^
    | 
-  ::: $DIR/group-compat-hack.rs:54:5
+  ::: $DIR/group-compat-hack.rs:55:5
    |
 LL |     tuple_from_req!(Foo);
    |     --------------------- in this macro invocation
@@ -53,7 +69,7 @@ warning: using an old version of `actix-web`
 LL |         #[my_macro] struct Three($T);
    |                                  ^^
    | 
-  ::: $DIR/group-compat-hack.rs:62:5
+  ::: $DIR/group-compat-hack.rs:63:5
    |
 LL |     tuple_from_req!(Foo);
    |     --------------------- in this macro invocation
@@ -63,7 +79,7 @@ LL |     tuple_from_req!(Foo);
    = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage
    = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-warning: 4 warnings emitted
+warning: 5 warnings emitted
 
 Future incompatibility report: Future breakage date: None, diagnostic:
 warning: using an old version of `time-macros-impl`
@@ -101,13 +117,30 @@ LL |     impl_macros!(Foo);
    = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage date: None, diagnostic:
+warning: using an old version of `js-sys`
+  --> $DIR/js-sys-0.3.17/src/lib.rs:5:32
+   |
+LL |         #[my_macro] struct Two($name);
+   |                                ^^^^^
+   | 
+  ::: $DIR/group-compat-hack.rs:46:5
+   |
+LL |     arrays!(Foo);
+   |     ------------- in this macro invocation
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `js-sys` crate will stop compiling in future versions of Rust; please update to `js-sys` v0.3.40 or above
+   = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage date: None, diagnostic:
 warning: using an old version of `actix-web`
   --> $DIR/actix-web/src/extract.rs:5:34
    |
 LL |         #[my_macro] struct Three($T);
    |                                  ^^
    | 
-  ::: $DIR/group-compat-hack.rs:54:5
+  ::: $DIR/group-compat-hack.rs:55:5
    |
 LL |     tuple_from_req!(Foo);
    |     --------------------- in this macro invocation
@@ -124,7 +157,7 @@ warning: using an old version of `actix-web`
 LL |         #[my_macro] struct Three($T);
    |                                  ^^
    | 
-  ::: $DIR/group-compat-hack.rs:62:5
+  ::: $DIR/group-compat-hack.rs:63:5
    |
 LL |     tuple_from_req!(Foo);
    |     --------------------- in this macro invocation
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
index 3fe744e12ff..82d6bc33bf9 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
@@ -1,10 +1,11 @@
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl/src/lib.rs:5:21: 5:27 (#6) }, Ident { ident: "One", span: $DIR/time-macros-impl/src/lib.rs:5:28: 5:31 (#6) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:27:18: 27:21 (#0) }], span: $DIR/time-macros-impl/src/lib.rs:5:31: 5:38 (#6) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl/src/lib.rs:5:38: 5:39 (#6) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#10) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#10) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:13: 29:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#10) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#10) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#10) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#10) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:13: 29:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:32: 5:37 (#10) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#10) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#10) }]
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:22:25: 22:31 (#14) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:22:32: 22:37 (#14) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:30:12: 30:15 (#0) }], span: $DIR/group-compat-hack.rs:22:38: 22:43 (#14) }], span: $DIR/group-compat-hack.rs:22:37: 22:44 (#14) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:22:44: 22:45 (#14) }]
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:21: 5:27 (#20) }, Ident { ident: "One", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:28: 5:31 (#20) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:44:18: 44:21 (#0) }], span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:31: 5:38 (#20) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:38: 5:39 (#20) }]
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#24) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#24) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:46:13: 46:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#24) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#24) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:39:25: 39:31 (#28) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:39:32: 39:37 (#28) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:47:12: 47:15 (#0) }], span: $DIR/group-compat-hack.rs:39:38: 39:43 (#28) }], span: $DIR/group-compat-hack.rs:39:37: 39:44 (#28) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:39:44: 39:45 (#28) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web/src/extract.rs:5:21: 5:27 (#33) }, Ident { ident: "Three", span: $DIR/actix-web/src/extract.rs:5:28: 5:33 (#33) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:54:21: 54:24 (#0) }], span: $DIR/actix-web/src/extract.rs:5:33: 5:37 (#33) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web/src/extract.rs:5:37: 5:38 (#33) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web-2.0.0/src/extract.rs:5:21: 5:27 (#38) }, Ident { ident: "Three", span: $DIR/actix-web-2.0.0/src/extract.rs:5:28: 5:33 (#38) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:62:21: 62:24 (#0) }], span: $DIR/actix-web-2.0.0/src/extract.rs:5:33: 5:37 (#38) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web-2.0.0/src/extract.rs:5:37: 5:38 (#38) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web/src/extract.rs:5:21: 5:27 (#43) }, Ident { ident: "Four", span: $DIR/actori-web/src/extract.rs:5:28: 5:32 (#43) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:70:21: 70:24 (#0) }], span: $DIR/actori-web/src/extract.rs:5:33: 5:35 (#43) }], span: $DIR/actori-web/src/extract.rs:5:32: 5:36 (#43) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web/src/extract.rs:5:36: 5:37 (#43) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web-2.0.0/src/extract.rs:5:21: 5:27 (#48) }, Ident { ident: "Four", span: $DIR/actori-web-2.0.0/src/extract.rs:5:28: 5:32 (#48) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:77:21: 77:24 (#0) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:33: 5:35 (#48) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:32: 5:36 (#48) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web-2.0.0/src/extract.rs:5:36: 5:37 (#48) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:39:25: 39:31 (#28) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:39:32: 39:37 (#28) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:48:12: 48:15 (#0) }], span: $DIR/group-compat-hack.rs:39:38: 39:43 (#28) }], span: $DIR/group-compat-hack.rs:39:37: 39:44 (#28) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:39:44: 39:45 (#28) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web/src/extract.rs:5:21: 5:27 (#33) }, Ident { ident: "Three", span: $DIR/actix-web/src/extract.rs:5:28: 5:33 (#33) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:55:21: 55:24 (#0) }], span: $DIR/actix-web/src/extract.rs:5:33: 5:37 (#33) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web/src/extract.rs:5:37: 5:38 (#33) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web-2.0.0/src/extract.rs:5:21: 5:27 (#38) }, Ident { ident: "Three", span: $DIR/actix-web-2.0.0/src/extract.rs:5:28: 5:33 (#38) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:63:21: 63:24 (#0) }], span: $DIR/actix-web-2.0.0/src/extract.rs:5:33: 5:37 (#38) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web-2.0.0/src/extract.rs:5:37: 5:38 (#38) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web/src/extract.rs:5:21: 5:27 (#43) }, Ident { ident: "Four", span: $DIR/actori-web/src/extract.rs:5:28: 5:32 (#43) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:71:21: 71:24 (#0) }], span: $DIR/actori-web/src/extract.rs:5:33: 5:35 (#43) }], span: $DIR/actori-web/src/extract.rs:5:32: 5:36 (#43) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web/src/extract.rs:5:36: 5:37 (#43) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web-2.0.0/src/extract.rs:5:21: 5:27 (#48) }, Ident { ident: "Four", span: $DIR/actori-web-2.0.0/src/extract.rs:5:28: 5:32 (#48) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:78:21: 78:24 (#0) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:33: 5:35 (#48) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:32: 5:36 (#48) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web-2.0.0/src/extract.rs:5:36: 5:37 (#48) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.40/src/lib.rs:5:21: 5:27 (#53) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.40/src/lib.rs:5:28: 5:31 (#53) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:84:13: 84:16 (#0) }], span: $DIR/js-sys-0.3.40/src/lib.rs:5:32: 5:37 (#53) }], span: $DIR/js-sys-0.3.40/src/lib.rs:5:31: 5:38 (#53) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.40/src/lib.rs:5:38: 5:39 (#53) }]
diff --git a/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.40/src/lib.rs b/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.40/src/lib.rs
new file mode 100644
index 00000000000..d1a66940ebf
--- /dev/null
+++ b/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.40/src/lib.rs
@@ -0,0 +1,7 @@
+// ignore-test this is not a test
+
+macro_rules! arrays {
+    ($name:ident) => {
+        #[my_macro] struct Two($name);
+    }
+}
diff --git a/src/test/ui/no-implicit-prelude.rs b/src/test/ui/resolve/no-implicit-prelude.rs
index 4b0ca4d524e..4b0ca4d524e 100644
--- a/src/test/ui/no-implicit-prelude.rs
+++ b/src/test/ui/resolve/no-implicit-prelude.rs
diff --git a/src/test/ui/no-implicit-prelude.stderr b/src/test/ui/resolve/no-implicit-prelude.stderr
index 36a9b65b7d1..36a9b65b7d1 100644
--- a/src/test/ui/no-implicit-prelude.stderr
+++ b/src/test/ui/resolve/no-implicit-prelude.stderr
diff --git a/src/test/ui/issues/issue-1701.rs b/src/test/ui/structs-enums/issue-1701.rs
index bae32a77765..bae32a77765 100644
--- a/src/test/ui/issues/issue-1701.rs
+++ b/src/test/ui/structs-enums/issue-1701.rs
diff --git a/src/test/ui/issues/issue-78372.rs b/src/test/ui/traits/issue-78372.rs
index 77a8c92c81c..77a8c92c81c 100644
--- a/src/test/ui/issues/issue-78372.rs
+++ b/src/test/ui/traits/issue-78372.rs
diff --git a/src/test/ui/issues/issue-78372.stderr b/src/test/ui/traits/issue-78372.stderr
index 9267e838cea..9267e838cea 100644
--- a/src/test/ui/issues/issue-78372.stderr
+++ b/src/test/ui/traits/issue-78372.stderr
diff --git a/src/test/ui/issues/issue-65611.rs b/src/test/ui/typeck/issue-65611.rs
index b74ee1b0c6e..b74ee1b0c6e 100644
--- a/src/test/ui/issues/issue-65611.rs
+++ b/src/test/ui/typeck/issue-65611.rs
diff --git a/src/test/ui/issues/issue-65611.stderr b/src/test/ui/typeck/issue-65611.stderr
index e3c005a0593..e3c005a0593 100644
--- a/src/test/ui/issues/issue-65611.stderr
+++ b/src/test/ui/typeck/issue-65611.stderr
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 8aebce67917..3e1db233696 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -181,7 +181,15 @@ fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: D
 
     let result = cx
         .tcx
-        .const_eval_resolve(cx.param_env, ty::WithOptConstParam::unknown(def_id), substs, None, None);
+        .const_eval_resolve(
+            cx.param_env,
+            ty::Unevaluated {
+                def: ty::WithOptConstParam::unknown(def_id),
+                substs,
+                promoted: None
+            },
+            None
+        );
     is_value_unfrozen_raw(cx, result, ty)
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 802c01055a6..ebe896b7ae8 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -341,9 +341,11 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                     .tcx
                     .const_eval_resolve(
                         self.param_env,
-                        ty::WithOptConstParam::unknown(def_id),
-                        substs,
-                        None,
+                        ty::Unevaluated {
+                            def: ty::WithOptConstParam::unknown(def_id),
+                            substs,
+                            promoted: None,
+                        },
                         None,
                     )
                     .ok()
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 3374a8c9b73..7cc660454b4 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -7,8 +7,8 @@ use std::path::Path;
 
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 1408;
-const ISSUES_ENTRY_LIMIT: usize = 2565;
+const ROOT_ENTRY_LIMIT: usize = 1390;
+const ISSUES_ENTRY_LIMIT: usize = 2551;
 
 fn check_entries(path: &Path, bad: &mut bool) {
     let dirs = walkdir::WalkDir::new(&path.join("test/ui"))