From 43ebac119b853de626fcc9afb49c5b0544731141 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 12 Mar 2021 00:01:34 +0100 Subject: [PATCH] extract `ConstKind::Unevaluated` into a struct --- .../rustc_codegen_ssa/src/mir/constant.rs | 2 +- compiler/rustc_middle/src/ty/consts.rs | 12 ++--- compiler/rustc_middle/src/ty/consts/kind.rs | 16 ++++-- compiler/rustc_middle/src/ty/flags.rs | 10 ++-- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/relate.rs | 24 ++++----- .../rustc_middle/src/ty/structural_impls.rs | 10 ++-- compiler/rustc_middle/src/ty/walk.rs | 4 +- .../src/borrow_check/type_check/mod.rs | 6 +-- compiler/rustc_mir/src/interpret/operand.rs | 2 +- .../rustc_mir/src/monomorphize/collector.rs | 2 +- .../src/monomorphize/polymorphize.rs | 6 +-- .../src/transform/check_consts/qualifs.rs | 2 +- .../rustc_mir/src/transform/const_prop.rs | 6 ++- compiler/rustc_mir/src/transform/inline.rs | 2 +- .../rustc_mir/src/transform/promote_consts.rs | 8 +-- .../src/transform/required_consts.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 16 +++--- .../src/traits/auto_trait.rs | 7 ++- .../src/traits/const_evaluatable.rs | 49 ++++++++++++------- .../src/traits/fulfill.rs | 15 +++--- .../src/traits/select/mod.rs | 7 ++- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 5 +- 25 files changed, 131 insertions(+), 88 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index aa41acc3578..d1425523275 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -30,7 +30,7 @@ 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(ty::Unevaluated { def, substs, promoted }) => self .cx .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None) 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..be1975785b1 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, + pub substs: SubstsRef<'tcx>, + pub promoted: Option, +} /// 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, SubstsRef<'tcx>, Option), + 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, 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` 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>( 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..a4c90a5f68f 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -646,7 +646,7 @@ 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) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) { Ok(val) => collect_const_value(self.tcx, val, self.output), Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} 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: // `>::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_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..495758cedb1 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -803,7 +803,12 @@ 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(ty::Unevaluated { + def, + substs, + promoted, + }) = c.val + { match select.infcx().const_eval_resolve( obligation.param_env, def, diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 670527fb3f0..a5db742136a 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -239,7 +239,9 @@ impl AbstractConst<'tcx> { ct: &ty::Const<'tcx>, ) -> Result>, 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 +534,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()); - // `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))); + 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_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 +678,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/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 7d451fc2341..83b537a7895 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -516,15 +516,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,7 +532,12 @@ 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(ty::Unevaluated { + def, + substs, + promoted, + }) = c.val + { match self.selcx.infcx().const_eval_resolve( obligation.param_env, def, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45b5aff40a6..14cec0029f2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -556,7 +556,12 @@ 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(ty::Unevaluated { + def, + substs, + promoted, + }) = c.val + { self.infcx .const_eval_resolve( obligation.param_env, 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, )); }