diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 7a8ce621c5d0..63b2088f7fc0 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -2,6 +2,7 @@ use rustc_index::vec::IndexVec; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::{Body, Location, Promoted}; +use rustc_middle::mir::{Constant, ConstantKind}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -37,6 +38,21 @@ where }) } +// FIXME(valtrees): This function is necessary because `fold_regions` +// panics for mir constants in the visitor. +// +// Once `visit_mir_constant` is removed we can also remove this function +// and just use `renumber_regions`. +fn renumber_regions_in_mir_constant<'tcx>( + infcx: &InferCtxt<'_, 'tcx>, + value: ConstantKind<'tcx>, +) -> ConstantKind<'tcx> { + infcx.tcx.super_fold_regions(value, |_region, _depth| { + let origin = NllRegionVariableOrigin::Existential { from_forall: false }; + infcx.next_nll_region_var(origin) + }) +} + struct NllVisitor<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, } @@ -48,6 +64,13 @@ impl<'a, 'tcx> NllVisitor<'a, 'tcx> { { renumber_regions(self.infcx, value) } + + fn renumber_regions_in_mir_constant( + &mut self, + value: ConstantKind<'tcx>, + ) -> ConstantKind<'tcx> { + renumber_regions_in_mir_constant(self.infcx, value) + } } impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { @@ -77,7 +100,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { debug!(?region); } - fn visit_const(&mut self, constant: &mut ty::Const<'tcx>, _location: Location) { - *constant = self.renumber_regions(*constant); + #[instrument(skip(self), level = "debug")] + fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) { + let literal = constant.literal; + constant.literal = self.renumber_regions_in_mir_constant(literal); + debug!("constant: {:#?}", constant); } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index fc0e95f30c98..500f9ae08c5b 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -354,11 +354,15 @@ 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.kind() { - ty::ConstKind::Unevaluated(uv) => Some(uv), + ty::ConstKind::Unevaluated(_) => { + bug!("should not encounter unevaluated ConstantKind::Ty here, got {:?}", ct) + } _ => None, }, + ConstantKind::Unevaluated(uv, _) => Some(uv), _ => None, }; + if let Some(uv) = maybe_uneval { if let Some(promoted) = uv.promoted { let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, @@ -1812,12 +1816,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) { if let Operand::Constant(constant) = op { let maybe_uneval = match constant.literal { - ConstantKind::Ty(ct) => match ct.kind() { - ty::ConstKind::Unevaluated(uv) => Some(uv), - _ => None, - }, - _ => None, + ConstantKind::Val(..) | ConstantKind::Ty(_) => None, + ConstantKind::Unevaluated(uv, _) => Some(uv), }; + if let Some(uv) = maybe_uneval { if uv.promoted.is_none() { let tcx = self.tcx(); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 0305341da784..6b4ed9b9d405 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -41,36 +41,30 @@ impl ConstantCx { pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { let mut all_constants_ok = true; for constant in &fx.mir.required_consts { - let const_ = match fx.monomorphize(constant.literal) { - ConstantKind::Ty(ct) => ct, + let unevaluated = match fx.monomorphize(constant.literal) { + ConstantKind::Ty(ct) => match ct.kind() { + ConstKind::Unevaluated(uv) => uv.expand(), + ConstKind::Value(_) => continue, + ConstKind::Param(_) + | ConstKind::Infer(_) + | ConstKind::Bound(_, _) + | ConstKind::Placeholder(_) + | ConstKind::Error(_) => unreachable!("{:?}", ct), + }, + ConstantKind::Unevaluated(uv, _) => uv, ConstantKind::Val(..) => continue, }; - match const_.kind() { - ConstKind::Value(_) => {} - ConstKind::Unevaluated(unevaluated) => { - if let Err(err) = - fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) - { - all_constants_ok = false; - match err { - ErrorHandled::Reported(_) | ErrorHandled::Linted => { - fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); - } - ErrorHandled::TooGeneric => { - span_bug!( - constant.span, - "codegen encountered polymorphic constant: {:?}", - err - ); - } - } + + if let Err(err) = fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { + all_constants_ok = false; + match err { + ErrorHandled::Reported(_) | ErrorHandled::Linted => { + fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); + } + ErrorHandled::TooGeneric => { + span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err); } } - ConstKind::Param(_) - | ConstKind::Infer(_) - | ConstKind::Bound(_, _) - | ConstKind::Placeholder(_) - | ConstKind::Error(_) => unreachable!("{:?}", const_), } } all_constants_ok @@ -122,36 +116,28 @@ pub(crate) fn codegen_constant<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { - let const_ = match fx.monomorphize(constant.literal) { - ConstantKind::Ty(ct) => ct, - ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty), - }; - let const_val = match const_.kind() { - ConstKind::Value(valtree) => fx.tcx.valtree_to_const_val((const_.ty(), valtree)), - ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + let (const_val, ty) = match fx.monomorphize(constant.literal) { + ConstantKind::Ty(const_) => unreachable!("{:?}", const_), + ConstantKind::Unevaluated(ty::Unevaluated { def, substs, promoted }, ty) 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); + return codegen_static_ref(fx, def.did, fx.layout_of(ty)).to_cvalue(fx); } - ConstKind::Unevaluated(unevaluated) => { + ConstantKind::Unevaluated(unevaluated, ty) => { match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { - Ok(const_val) => const_val, + Ok(const_val) => (const_val, ty), Err(_) => { span_bug!(constant.span, "erroneous constant not captured by required_consts"); } } } - ConstKind::Param(_) - | ConstKind::Infer(_) - | ConstKind::Bound(_, _) - | ConstKind::Placeholder(_) - | ConstKind::Error(_) => unreachable!("{:?}", const_), + ConstantKind::Val(val, ty) => (val, ty), }; - codegen_const_value(fx, const_val, const_.ty()) + codegen_const_value(fx, const_val, ty) } pub(crate) fn codegen_const_value<'tcx>( @@ -496,6 +482,9 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( .eval_for_mir(fx.tcx, ParamEnv::reveal_all()) .try_to_value(fx.tcx), ConstantKind::Val(val, _) => Some(val), + ConstantKind::Unevaluated(uv, _) => { + fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), uv, None).ok() + } }, // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored // inside a temporary before being passed to the intrinsic requiring the const argument. diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 9a995fbf65ca..4c6ab457c494 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -25,26 +25,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { let ct = self.monomorphize(constant.literal); - let ct = match ct { - mir::ConstantKind::Ty(ct) => ct, + let uv = match ct { + mir::ConstantKind::Ty(ct) => match ct.kind() { + ty::ConstKind::Unevaluated(uv) => uv.expand(), + ty::ConstKind::Value(val) => { + return Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val))); + } + err => span_bug!( + constant.span, + "encountered bad ConstKind after monomorphizing: {:?}", + err + ), + }, + mir::ConstantKind::Unevaluated(uv, _) => uv, mir::ConstantKind::Val(val, _) => return Ok(val), }; - match ct.kind() { - ty::ConstKind::Unevaluated(ct) => self - .cx - .tcx() - .const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None) - .map_err(|err| { - self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); - err - }), - ty::ConstKind::Value(val) => Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val))), - err => span_bug!( - constant.span, - "encountered bad ConstKind after monomorphizing: {:?}", - err - ), - } + + self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| { + self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); + err + }) } /// process constant containing SIMD shuffle indices diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index f6c4f7dd1122..29c745a0886f 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -564,8 +564,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_inval!(AlreadyReported(reported)) } ty::ConstKind::Unevaluated(uv) => { + // NOTE: We evaluate to a `ValTree` here as a check to ensure + // we're working with valid constants, even though we never need it. let instance = self.resolve(uv.def, uv.substs)?; - Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) + let cid = GlobalId { instance, promoted: None }; + let _valtree = self + .tcx + .eval_to_valtree(self.param_env.and(cid))? + .unwrap_or_else(|| bug!("unable to create ValTree for {:?}", uv)); + + Ok(self.eval_to_allocation(cid)?.into()) } ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c) @@ -586,6 +594,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match val { mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout), mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout), + mir::ConstantKind::Unevaluated(uv, _) => { + let instance = self.resolve(uv.def, uv.substs)?; + Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) + } } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 45dadcfff2e5..6c73ef5a8fa0 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -346,31 +346,43 @@ where }; // Check the qualifs of the value of `const` items. - if let Some(ct) = constant.literal.const_for_ty() { - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.kind() - { - // Use qualifs of the type for the promoted. Promoteds in MIR body should be possible - // only for `NeedsNonConstDrop` with precise drop checking. This is the only const - // check performed after the promotion. Verify that with an assertion. - assert!(promoted.is_none() || Q::ALLOW_PROMOTED); - // Don't peek inside trait associated constants. - if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() { - let qualifs = if let Some((did, param_did)) = def.as_const_arg() { - cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did)) - } else { - cx.tcx.at(constant.span).mir_const_qualif(def.did) - }; - - if !Q::in_qualifs(&qualifs) { - return false; - } + // FIXME(valtrees): check whether const qualifs should behave the same + // way for type and mir constants. + let uneval = match constant.literal { + ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Unevaluated(_)) => { + let ty::ConstKind::Unevaluated(uv) = ct.kind() else { unreachable!() }; - // Just in case the type is more specific than - // the definition, e.g., impl associated const - // with type parameters, take it into account. + Some(uv.expand()) + } + ConstantKind::Ty(_) => None, + ConstantKind::Unevaluated(uv, _) => Some(uv), + ConstantKind::Val(..) => None, + }; + + if let Some(ty::Unevaluated { def, substs: _, promoted }) = uneval { + // Use qualifs of the type for the promoted. Promoteds in MIR body should be possible + // only for `NeedsNonConstDrop` with precise drop checking. This is the only const + // check performed after the promotion. Verify that with an assertion. + assert!(promoted.is_none() || Q::ALLOW_PROMOTED); + + // Don't peek inside trait associated constants. + if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() { + let qualifs = if let Some((did, param_did)) = def.as_const_arg() { + cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did)) + } else { + cx.tcx.at(constant.span).mir_const_qualif(def.did) + }; + + if !Q::in_qualifs(&qualifs) { + return false; } + + // Just in case the type is more specific than + // the definition, e.g., impl associated const + // with type parameters, take it into account. } } + // Otherwise use the qualifs of the type. Q::in_any_value_of_ty(cx, constant.literal.ty()) } diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index f5ba408bee0e..f7a7cc88a525 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -840,21 +840,15 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did)); - let _const = tcx.mk_const(ty::ConstS { - ty, - kind: ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs, - promoted: Some(promoted_id), - }), - }); + let uneval = ty::Unevaluated { def, substs, promoted: Some(promoted_id) }; Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: ConstantKind::from_const(_const, tcx), + literal: ConstantKind::Unevaluated(uneval, ty), })) }; + let blocks = self.source.basic_blocks.as_mut(); let local_decls = &mut self.source.local_decls; let loc = candidate.location; diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 524383e381fe..c406df9e4111 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -743,7 +743,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - assert_eq!(promoted, None); + assert_eq!(promoted, ()); + let substs = self.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), @@ -964,13 +965,15 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - assert_eq!(promoted, None); + assert_eq!(promoted, ()); + let substs = self.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), substs, substs, )?; + Ok(self.tcx().mk_const(ty::ConstS { ty: c.ty(), kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bbbc044b85a4..088fb0a85ab1 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1673,7 +1673,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn try_const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, - unevaluated: ty::Unevaluated<'tcx>, + unevaluated: ty::Unevaluated<'tcx, ()>, ty: Ty<'tcx>, span: Option, ) -> Result, ErrorHandled> { @@ -1708,7 +1708,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn const_eval_resolve( &self, mut param_env: ty::ParamEnv<'tcx>, - unevaluated: ty::Unevaluated<'tcx>, + unevaluated: ty::Unevaluated<'tcx, ()>, span: Option, ) -> EvalToValTreeResult<'tcx> { let mut substs = self.resolve_vars_if_possible(unevaluated.substs); @@ -1717,7 +1717,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Postpone the evaluation of constants whose substs depend on inference // variables if substs.has_infer_types_or_consts() { - let ac = AbstractConst::new(self.tcx, unevaluated.shrink()); + let ac = AbstractConst::new(self.tcx, unevaluated); match ac { Ok(None) => { substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did); @@ -1739,11 +1739,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!(?param_env_erased); debug!(?substs_erased); - let unevaluated = ty::Unevaluated { - def: unevaluated.def, - substs: substs_erased, - promoted: unevaluated.promoted, - }; + let unevaluated = + ty::Unevaluated { def: unevaluated.def, substs: substs_erased, promoted: () }; // 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. diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 786927e2dad7..4207988d700d 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -63,7 +63,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn const_eval_resolve_for_typeck( self, param_env: ty::ParamEnv<'tcx>, - ct: ty::Unevaluated<'tcx>, + ct: ty::Unevaluated<'tcx, ()>, span: Option, ) -> EvalToValTreeResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference @@ -78,7 +78,7 @@ impl<'tcx> TyCtxt<'tcx> { match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { Ok(Some(instance)) => { - let cid = GlobalId { instance, promoted: ct.promoted }; + let cid = GlobalId { instance, promoted: None }; self.const_eval_global_id_for_typeck(param_env, cid, span) } Ok(None) => Err(ErrorHandled::TooGeneric), diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index dd768c5358d5..2fddb00d719c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -3,7 +3,7 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html use crate::mir::interpret::{ - AllocRange, ConstAllocation, ConstValue, GlobalAlloc, LitToConstInput, Scalar, + AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, LitToConstInput, Scalar, }; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; @@ -2061,6 +2061,10 @@ pub struct Constant<'tcx> { pub enum ConstantKind<'tcx> { /// This constant came from the type system Ty(ty::Const<'tcx>), + + /// An unevaluated mir constant which is not part of the type system. + Unevaluated(ty::Unevaluated<'tcx, Option>, Ty<'tcx>), + /// This constant cannot go back into the type system, as it represents /// something the type system cannot handle (e.g. pointers). Val(interpret::ConstValue<'tcx>, Ty<'tcx>), @@ -2086,20 +2090,11 @@ impl<'tcx> Constant<'tcx> { } impl<'tcx> ConstantKind<'tcx> { - /// Returns `None` if the constant is not trivially safe for use in the type system. - #[inline] - pub fn const_for_ty(&self) -> Option> { - match self { - ConstantKind::Ty(c) => Some(*c), - ConstantKind::Val(..) => None, - } - } - #[inline(always)] pub fn ty(&self) -> Ty<'tcx> { match self { ConstantKind::Ty(c) => c.ty(), - ConstantKind::Val(_, ty) => *ty, + ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => *ty, } } @@ -2111,6 +2106,7 @@ impl<'tcx> ConstantKind<'tcx> { _ => None, }, ConstantKind::Val(val, _) => Some(val), + ConstantKind::Unevaluated(..) => None, } } @@ -2125,6 +2121,7 @@ impl<'tcx> ConstantKind<'tcx> { _ => None, }, ConstantKind::Val(val, _) => val.try_to_scalar(), + ConstantKind::Unevaluated(..) => None, } } @@ -2157,6 +2154,14 @@ impl<'tcx> ConstantKind<'tcx> { } } Self::Val(_, _) => self, + Self::Unevaluated(uneval, ty) => { + // FIXME: We might want to have a `try_eval`-like function on `Unevaluated` + match tcx.const_eval_resolve(param_env, uneval, None) { + Ok(val) => Self::Val(val, ty), + Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self, + Err(_) => Self::Ty(tcx.const_error(ty)), + } + } } } @@ -2182,6 +2187,18 @@ impl<'tcx> ConstantKind<'tcx> { tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; val.try_to_bits(size) } + Self::Unevaluated(uneval, ty) => { + match tcx.const_eval_resolve(param_env, *uneval, None) { + Ok(val) => { + let size = tcx + .layout_of(param_env.with_reveal_all_normalized(tcx).and(*ty)) + .ok()? + .size; + val.try_to_bits(size) + } + Err(_) => None, + } + } } } @@ -2190,6 +2207,12 @@ impl<'tcx> ConstantKind<'tcx> { match self { Self::Ty(ct) => ct.try_eval_bool(tcx, param_env), Self::Val(val, _) => val.try_to_bool(), + Self::Unevaluated(uneval, _) => { + match tcx.const_eval_resolve(param_env, *uneval, None) { + Ok(val) => val.try_to_bool(), + Err(_) => None, + } + } } } @@ -2198,6 +2221,12 @@ impl<'tcx> ConstantKind<'tcx> { match self { Self::Ty(ct) => ct.try_eval_usize(tcx, param_env), Self::Val(val, _) => val.try_to_machine_usize(tcx), + Self::Unevaluated(uneval, _) => { + match tcx.const_eval_resolve(param_env, *uneval, None) { + Ok(val) => val.try_to_machine_usize(tcx), + Err(_) => None, + } + } } } @@ -2293,15 +2322,16 @@ impl<'tcx> ConstantKind<'tcx> { let substs = ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty }) .substs; - debug_assert!(!substs.has_free_regions()); - Self::Ty(tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(ty::Unevaluated { - def: ty::WithOptConstParam::unknown(def_id).to_global(), - substs, - promoted: None, - }), - ty, - })) + + let uneval = ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id).to_global(), + substs, + promoted: None, + }; + + debug_assert!(!uneval.has_free_regions()); + + Self::Unevaluated(uneval, ty) } #[instrument(skip(tcx), level = "debug", ret)] @@ -2394,14 +2424,14 @@ impl<'tcx> ConstantKind<'tcx> { debug!("error encountered during evaluation"); // Error was handled in `const_eval_resolve`. Here we just create a // new unevaluated const and error hard later in codegen - Self::Ty(tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(ty::Unevaluated { + Self::Unevaluated( + ty::Unevaluated { def: def.to_global(), substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), promoted: None, - }), + }, ty, - })) + ) } } } @@ -2412,6 +2442,7 @@ impl<'tcx> ConstantKind<'tcx> { let const_val = tcx.valtree_to_const_val((c.ty(), valtree)); Self::Val(const_val, c.ty()) } + ty::ConstKind::Unevaluated(uv) => Self::Unevaluated(uv.expand(), c.ty()), _ => Self::Ty(c), } } @@ -2612,6 +2643,11 @@ impl<'tcx> Display for ConstantKind<'tcx> { match *self { ConstantKind::Ty(c) => pretty_print_const(c, fmt, true), ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true), + // FIXME(valtrees): Correctly print mir constants. + ConstantKind::Unevaluated(..) => { + fmt.write_str("_")?; + Ok(()) + } } } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 88c16189f1dc..0b42137d4e3c 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -464,12 +464,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { let val = match literal { ConstantKind::Ty(ct) => match ct.kind() { ty::ConstKind::Param(p) => format!("Param({})", p), - ty::ConstKind::Unevaluated(uv) => format!( - "Unevaluated({}, {:?}, {:?})", - self.tcx.def_path_str(uv.def.did), - uv.substs, - uv.promoted, - ), + ty::ConstKind::Unevaluated(uv) => { + format!( + "Unevaluated({}, {:?}, {:?})", + self.tcx.def_path_str(uv.def.did), + uv.substs, + uv.promoted, + ) + } ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)), ty::ConstKind::Error(_) => "Error".to_string(), // These variants shouldn't exist in the MIR. @@ -477,6 +479,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { | ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) => bug!("unexpected MIR constant: {:?}", literal), }, + ConstantKind::Unevaluated(uv, _) => { + format!( + "Unevaluated({}, {:?}, {:?})", + self.tcx.def_path_str(uv.def.did), + uv.substs, + uv.promoted, + ) + } // To keep the diffs small, we render this like we render `ty::Const::Value`. // // This changes once `ty::Const::Value` is represented using valtrees. @@ -696,9 +706,9 @@ pub fn write_allocations<'tcx>( struct CollectAllocIds(BTreeSet); impl<'tcx> Visitor<'tcx> for CollectAllocIds { - fn visit_constant(&mut self, c: &Constant<'tcx>, loc: Location) { + fn visit_constant(&mut self, c: &Constant<'tcx>, _: Location) { match c.literal { - ConstantKind::Ty(c) => self.visit_const(c, loc), + ConstantKind::Ty(_) | ConstantKind::Unevaluated(..) => {} ConstantKind::Val(val, _) => { self.0.extend(alloc_ids_from_const_val(val)); } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 82a6b0c506f5..022ec6f074db 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -235,6 +235,9 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> { match self { ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)), ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)), + ConstantKind::Unevaluated(uv, t) => { + Ok(ConstantKind::Unevaluated(uv.try_fold_with(folder)?, t.try_fold_with(folder)?)) + } } } } diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs index 6a0801cb0dd2..4b3ad9cc5dad 100644 --- a/compiler/rustc_middle/src/mir/type_visitable.rs +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -185,6 +185,10 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> { match *self { ConstantKind::Ty(c) => c.visit_with(visitor), ConstantKind::Val(_, t) => t.visit_with(visitor), + ConstantKind::Unevaluated(uv, t) => { + uv.visit_with(visitor)?; + t.visit_with(visitor) + } } } } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 708ea4398c85..d9b24566bf14 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -237,14 +237,6 @@ macro_rules! make_mir_visitor { self.super_region(region); } - fn visit_const( - &mut self, - constant: $(& $mutability)? ty::Const<'tcx>, - _: Location, - ) { - self.super_const(constant); - } - fn visit_substs( &mut self, substs: & $($mutability)? SubstsRef<'tcx>, @@ -877,8 +869,9 @@ macro_rules! make_mir_visitor { self.visit_span($(& $mutability)? *span); drop(user_ty); // no visit method for this match literal { - ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location), + ConstantKind::Ty(_) => {} ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), + ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), } } @@ -916,9 +909,6 @@ macro_rules! make_mir_visitor { fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) { } - fn super_const(&mut self, _const: $(& $mutability)? ty::Const<'tcx>) { - } - fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) { } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index c50f8b0eebe1..a7649605e27e 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -826,9 +826,9 @@ mod size_asserts { static_assert_size!(Expr<'_>, 64); static_assert_size!(ExprKind<'_>, 40); #[cfg(not(bootstrap))] - static_assert_size!(Pat<'_>, 64); + static_assert_size!(Pat<'_>, 72); #[cfg(not(bootstrap))] - static_assert_size!(PatKind<'_>, 48); + static_assert_size!(PatKind<'_>, 56); #[cfg(not(bootstrap))] static_assert_size!(Stmt<'_>, 48); #[cfg(not(bootstrap))] diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index bed809930da6..8f79b4705ad6 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -42,7 +42,7 @@ impl<'tcx> AbstractConst<'tcx> { ct: ty::Const<'tcx>, ) -> Result>, ErrorGuaranteed> { match ct.kind() { - ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()), + ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv), ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported), _ => Ok(None), } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 2eb5cffa6bc4..339ff4d35930 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -41,7 +41,7 @@ pub struct ConstS<'tcx> { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ConstS<'_>, 48); +static_assert_size!(ConstS<'_>, 40); impl<'tcx> Const<'tcx> { #[inline] @@ -84,7 +84,7 @@ impl<'tcx> Const<'tcx> { kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), - promoted: None, + promoted: (), }), ty, }), @@ -181,7 +181,7 @@ impl<'tcx> Const<'tcx> { kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id).to_global(), substs, - promoted: None, + promoted: (), }), ty, }) diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ff20da65c016..3c21b89c97dd 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -11,6 +11,7 @@ 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, Lift)] #[derive(Hash, HashStable)] @@ -66,7 +67,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(Unevaluated<'tcx>), + Unevaluated(Unevaluated<'tcx, ()>), /// Used to hold computed value. Value(ty::ValTree<'tcx>), @@ -77,7 +78,7 @@ pub enum ConstKind<'tcx> { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ConstKind<'_>, 40); +static_assert_size!(ConstKind<'_>, 32); impl<'tcx> ConstKind<'tcx> { #[inline] @@ -184,6 +185,8 @@ impl<'tcx> ConstKind<'tcx> { if let ConstKind::Unevaluated(unevaluated) = self { use crate::mir::interpret::ErrorHandled; + assert_eq!(unevaluated.promoted, ()); + // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` // also does later, but we want to do it before checking for // inference variables. @@ -204,7 +207,7 @@ impl<'tcx> ConstKind<'tcx> { tcx.param_env(unevaluated.def.did).and(ty::Unevaluated { def: unevaluated.def, substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did), - promoted: unevaluated.promoted, + promoted: (), }) } else { param_env_and @@ -228,7 +231,7 @@ impl<'tcx> ConstKind<'tcx> { } } EvalMode::Mir => { - match tcx.const_eval_resolve(param_env, unevaluated, None) { + match tcx.const_eval_resolve(param_env, unevaluated.expand(), 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/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index cb46a9dba579..ed0eefd98ad8 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -302,6 +302,17 @@ impl<'tcx> TyCtxt<'tcx> { { value.fold_with(&mut RegionFolder::new(self, &mut f)) } + + pub fn super_fold_regions( + self, + value: T, + mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, + ) -> T + where + T: TypeSuperFoldable<'tcx>, + { + value.super_fold_with(&mut RegionFolder::new(self, &mut f)) + } } /// Folds over the substructure of a type, visiting its component diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e9eecfe78d32..afe97e5f92f9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1197,15 +1197,9 @@ pub trait PrettyPrinter<'tcx>: } match ct.kind() { - ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs, - promoted: Some(promoted), - }) => { - p!(print_value_path(def.did, substs)); - p!(write("::{:?}", promoted)); - } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { + assert_eq!(promoted, ()); + match self.tcx().def_kind(def.did) { DefKind::Static(..) | DefKind::Const | DefKind::AssocConst => { p!(print_value_path(def.did, substs)) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 81476195d299..488d9242b114 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -613,7 +613,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if tcx.features().generic_const_exprs => { - tcx.try_unify_abstract_consts(relation.param_env().and((au.shrink(), bu.shrink()))) + tcx.try_unify_abstract_consts(relation.param_env().and((au, bu))) } // While this is slightly incorrect, it shouldn't matter for `min_const_generics` @@ -622,6 +622,8 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def && au.promoted == bu.promoted => { + assert_eq!(au.promoted, ()); + let substs = relation.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), @@ -632,7 +634,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def: au.def, substs, - promoted: au.promoted, + promoted: (), }), ty: a.ty(), })); diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 3549b47478cb..c9bec130cc8f 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -2,26 +2,18 @@ use crate::build::{parse_float_into_constval, Builder}; use rustc_ast as ast; -use rustc_hir::def_id::DefId; use rustc_middle::mir::interpret::{ Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, }; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt}; +use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, TyCtxt}; use rustc_target::abi::Size; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that /// `expr` is a valid compile-time constant! pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> { - let create_uneval_from_def_id = - |tcx: TyCtxt<'tcx>, def_id: DefId, ty: Ty<'tcx>, substs: SubstsRef<'tcx>| { - let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); - tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty }) - }; - let this = self; let tcx = this.tcx; let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; @@ -73,7 +65,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { inferred_ty: ty, }) }); - let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs)); + + let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); + let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty, span, literal } } @@ -85,7 +79,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { user_ty: None, span, literal } } ExprKind::ConstBlock { did: def_id, substs } => { - let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs)); + let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); + let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty: None, span, literal } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 4968032b416b..ff80f732b40e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -565,23 +565,19 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let value = value.eval(self.tcx, self.param_env); match value { - mir::ConstantKind::Ty(c) => { - match c.kind() { - ConstKind::Param(_) => { - self.errors.push(PatternError::ConstParamInPattern(span)); - return PatKind::Wild; - } - ConstKind::Unevaluated(_) => { - // If we land here it means the const can't be evaluated because it's `TooGeneric`. - self.tcx - .sess - .span_err(span, "constant pattern depends on a generic parameter"); - return PatKind::Wild; - } - _ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"), + mir::ConstantKind::Ty(c) => match c.kind() { + ConstKind::Param(_) => { + self.errors.push(PatternError::ConstParamInPattern(span)); + return PatKind::Wild; } - } + _ => bug!("Expected ConstKind::Param"), + }, mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind, + mir::ConstantKind::Unevaluated(..) => { + // If we land here it means the const can't be evaluated because it's `TooGeneric`. + self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter"); + return PatKind::Wild; + } } } diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 082d6c9f07e5..37e78f4ac07d 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -22,9 +22,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; -use rustc_middle::ty::{ - self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable, -}; +use rustc_middle::ty::{self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable}; use rustc_session::lint; use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; @@ -301,18 +299,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let err = ConstEvalErr::new(&self.ecx, error, Some(c.span)); if let Some(lint_root) = self.lint_root(source_info) { let lint_only = match c.literal { - ConstantKind::Ty(ct) => match ct.kind() { + ConstantKind::Ty(ct) => ct.needs_subst(), + ConstantKind::Unevaluated( + ty::Unevaluated { def: _, substs: _, promoted: Some(_) }, + _, + ) => { // Promoteds must lint and not error as the user didn't ask for them - 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(), - }, - ConstantKind::Val(_, ty) => ty.needs_subst(), + true + } + ConstantKind::Unevaluated(..) | ConstantKind::Val(..) => c.needs_subst(), }; if lint_only { // Out of backwards compatibility we cannot report hard errors in unused diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index ba00f16308ea..d00a384cb44e 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -8,7 +8,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs} use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::def_id::DefId; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; @@ -604,11 +604,11 @@ impl<'tcx> Inliner<'tcx> { // `required_consts`, here we may not only have `ConstKind::Unevaluated` // because we are calling `subst_and_normalize_erasing_regions`. caller_body.required_consts.extend( - callee_body.required_consts.iter().copied().filter(|&ct| { - match ct.literal.const_for_ty() { - Some(ct) => matches!(ct.kind(), ConstKind::Unevaluated(_)), - None => true, + callee_body.required_consts.iter().copied().filter(|&ct| match ct.literal { + ConstantKind::Ty(_) => { + bug!("should never encounter ty::Unevaluated in `required_consts`") } + ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => true, }), ); } diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs index 827ce0c02ac4..cc75947d9dda 100644 --- a/compiler/rustc_mir_transform/src/required_consts.rs +++ b/compiler/rustc_mir_transform/src/required_consts.rs @@ -1,5 +1,5 @@ use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{Constant, Location}; +use rustc_middle::mir::{Constant, ConstantKind, Location}; use rustc_middle::ty::ConstKind; pub struct RequiredConstsVisitor<'a, 'tcx> { @@ -15,8 +15,13 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) { let literal = constant.literal; - if let Some(ct) = literal.const_for_ty() && let ConstKind::Unevaluated(_) = ct.kind() { - self.required_consts.push(*constant); + match literal { + ConstantKind::Ty(c) => match c.kind() { + ConstKind::Param(_) => {} + _ => bug!("only ConstKind::Param should be encountered here, got {:#?}", c), + }, + ConstantKind::Unevaluated(..) => self.required_consts.push(*constant), + ConstantKind::Val(..) => {} } } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index be74a9d11e3c..b7b24981217d 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -767,7 +767,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ty::ConstKind::Unevaluated(ct) => { debug!(?ct); let param_env = ty::ParamEnv::reveal_all(); - match self.tcx.const_eval_resolve(param_env, ct, None) { + match self.tcx.const_eval_resolve(param_env, ct.expand(), None) { // The `monomorphize` call should have evaluated that constant already. Ok(val) => val, Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, @@ -780,44 +780,22 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { } _ => return, }, - }; - collect_const_value(self.tcx, val, self.output); - self.visit_ty(literal.ty(), TyContext::Location(location)); - } - - #[instrument(skip(self), level = "debug")] - fn visit_const(&mut self, constant: ty::Const<'tcx>, location: Location) { - debug!("visiting const {:?} @ {:?}", constant, location); - - let substituted_constant = self.monomorphize(constant); - let param_env = ty::ParamEnv::reveal_all(); - - match substituted_constant.kind() { - ty::ConstKind::Value(val) => { - let const_val = self.tcx.valtree_to_const_val((constant.ty(), val)); - collect_const_value(self.tcx, const_val, self.output) - } - ty::ConstKind::Unevaluated(unevaluated) => { - match self.tcx.const_eval_resolve(param_env, unevaluated, None) { + mir::ConstantKind::Unevaluated(uv, _) => { + let param_env = ty::ParamEnv::reveal_all(); + match self.tcx.const_eval_resolve(param_env, uv, None) { // The `monomorphize` call should have evaluated that constant already. - Ok(val) => span_bug!( - self.body.source_info(location).span, - "collection encountered the unevaluated constant {} which evaluated to {:?}", - substituted_constant, - val - ), - Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => {} + Ok(val) => val, + Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, - "collection encountered polymorphic constant: {}", - substituted_constant + "collection encountered polymorphic constant: {:?}", + literal ), } } - _ => {} - } - - self.super_const(constant); + }; + collect_const_value(self.tcx, val, self.output); + MirVisitor::visit_ty(self, literal.ty(), TyContext::Location(location)); } fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) { diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 98156a94ec4b..71cab023215e 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -9,7 +9,7 @@ use rustc_hir::{def::DefKind, def_id::DefId, ConstContext}; use rustc_index::bit_set::FiniteBitSet; use rustc_middle::mir::{ visit::{TyContext, Visitor}, - Local, LocalDecl, Location, + Constant, ConstantKind, Local, LocalDecl, Location, }; use rustc_middle::ty::{ self, @@ -270,8 +270,15 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.super_local_decl(local, local_decl); } - fn visit_const(&mut self, c: Const<'tcx>, _: Location) { - c.visit_with(self); + fn visit_constant(&mut self, ct: &Constant<'tcx>, location: Location) { + match ct.literal { + ConstantKind::Ty(c) => { + c.visit_with(self); + } + ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => { + Visitor::visit_ty(self, ty, TyContext::Location(location)) + } + } } fn visit_ty(&mut self, ty: Ty<'tcx>, _: TyContext) { @@ -292,7 +299,26 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.unused_parameters.clear(param.index); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)}) + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) => + { + assert_eq!(promoted, ()); + + self.visit_child_body(def.did, substs); + ControlFlow::CONTINUE + } + _ => c.super_visit_with(self), + } + } + + fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow { + if !constant.has_param_types_or_consts() { + return ControlFlow::CONTINUE; + } + + match constant { + ConstantKind::Ty(ct) => ct.visit_with(self), + ConstantKind::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 => @@ -303,13 +329,9 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.visit_body(&promoted[p]); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(uv) - if matches!(self.tcx.def_kind(uv.def.did), DefKind::AnonConst | DefKind::InlineConst) => - { - self.visit_child_body(uv.def.did, uv.substs); - ControlFlow::CONTINUE + ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => { + constant.super_visit_with(self) } - _ => c.super_visit_with(self), } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 98e93ad3fc50..bcdfa4f12d35 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -834,7 +834,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let reported = tcx.sess.emit_err(UnableToConstructConstantValue { span: tcx.def_span(def_id), - unevaluated, + unevaluated: unevaluated.expand(), }); Err(ErrorHandled::Reported(reported)) } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 254bc4ab6638..5a213987e87b 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -183,7 +183,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( FailureKind::Concrete => {} } } - let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); + let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); match concrete { Err(ErrorHandled::TooGeneric) => { Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug( @@ -210,7 +210,7 @@ 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, uv.expand(), Some(span)); + let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); match concrete { // If we're evaluating a foreign constant, under a nightly compiler without generic diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 3763a98c488b..6bb6aef1d05c 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -509,11 +509,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.kind(), c2.kind()) { - if infcx.try_unify_abstract_consts( - a.shrink(), - b.shrink(), - obligation.param_env, - ) { + if infcx.try_unify_abstract_consts(a, b, obligation.param_env) { return ProcessResult::Changed(vec![]); } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index f65fc5bad0d9..17afd325f03a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -366,7 +366,9 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { _ => mir::ConstantKind::Ty(const_folded), } } - mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?, + mir::ConstantKind::Val(_, _) | mir::ConstantKind::Unevaluated(..) => { + constant.try_super_fold_with(self)? + } }) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8b15e10ba9cb..c8896027ba11 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -699,11 +699,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.kind(), c2.kind()) { - if self.infcx.try_unify_abstract_consts( - a.shrink(), - b.shrink(), - obligation.param_env, - ) { + if self.infcx.try_unify_abstract_consts(a, b, obligation.param_env) { return Ok(EvaluatedToOk); } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 9d3a1a4a031a..ff6b5c733868 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -456,7 +456,7 @@ impl<'tcx> WfPredicates<'tcx> { self.out.extend(obligations); let predicate = - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv)) .to_predicate(self.tcx()); let cause = self.cause(traits::WellFormed(None)); self.out.push(traits::Obligation::with_depth( diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index bb6b3e1ff5d7..44c4fc48d3f0 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -222,17 +222,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { debug!("AbstractConstBuilder::build: body={:?}", &*self.body); self.recurse_build(self.body_id)?; - for n in self.nodes.iter() { - if let Node::Leaf(ct) = n { - if let ty::ConstKind::Unevaluated(ct) = ct.kind() { - // `AbstractConst`s should not contain any promoteds as they require references which - // are not allowed. - assert_eq!(ct.promoted, None); - assert_eq!(ct, self.tcx.erase_regions(ct)); - } - } - } - Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter())) } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 3e7a6c3c5489..cbc4eab85fd5 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2372,10 +2372,10 @@ fn const_evaluatable_predicates_of<'tcx>( 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(uv) = ct.kind() { - assert_eq!(uv.promoted, None); + assert_eq!(uv.promoted, ()); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv)) .to_predicate(self.tcx), span, )); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 395f213ca87c..e87c09b69da3 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -235,14 +235,13 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => { - let mut s = if let Some(def) = def.as_local() { + assert_eq!(promoted, ()); + let s = if let Some(def) = def.as_local() { print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did)) } else { inline::print_inlined_const(cx.tcx, def.did) }; - if let Some(promoted) = promoted { - s.push_str(&format!("::{:?}", promoted)) - } + s } _ => { 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 b5439d9d2393..cf968f6fbb9c 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 @@ -17,7 +17,7 @@ - StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34 - StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 - _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34 -+ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 ++ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44 // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) } 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 4df4c9636a54..31f1a5597b34 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 @@ -19,7 +19,7 @@ - StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45 - StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 - _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43 -+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 ++ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55 // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } 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 55348883810f..c27b19679a83 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 @@ -25,7 +25,7 @@ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } 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 55348883810f..c27b19679a83 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 @@ -25,7 +25,7 @@ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - _9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } 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 2cb071deab13..bea7114c7df3 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 @@ -16,7 +16,7 @@ StorageLive(_1); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:9: +2:10 StorageLive(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:30 StorageLive(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 - _3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 + _3 = const _; // scope 0 at $DIR/const_prop_fails_gracefully.rs:+2:13: +2:16 // mir::Constant // + span: $DIR/const_prop_fails_gracefully.rs:8:13: 8:16 // + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) } diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff index 5f4df0d883bc..a07bdd99825d 100644 --- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff @@ -8,9 +8,8 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 -- _1 = const ::NEEDS; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 + _1 = const _; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 - switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 -+ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 + switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21 } 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 c8b09220f1e4..09ce67ff15dd 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 @@ -11,7 +11,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 - _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + _4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 // mir::Constant // + span: $DIR/ref_deref.rs:5:6: 5:10 // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } 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 d141d2cf87bb..902cd7850311 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 @@ -14,7 +14,7 @@ - StorageLive(_3); // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9 - _3 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9 - _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 -+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 ++ _4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + // mir::Constant + // + span: $DIR/ref_deref.rs:5:6: 5:10 + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } 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 84ec5c8bb1db..ec3d90433159 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 @@ -11,7 +11,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17 StorageLive(_2); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 - _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + _4 = const _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 // mir::Constant // + span: $DIR/ref_deref_project.rs:6:6: 6:17 // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) } 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 6f3a060a1260..cd0616e65baf 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 @@ -14,7 +14,7 @@ - StorageLive(_3); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14 - _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14 - _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 -+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 ++ _4 = const _; // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17 + // mir::Constant + // + span: $DIR/ref_deref_project.rs:6:6: 6:17 + // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) } 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 0ebfbca21391..624376769b70 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 @@ -19,7 +19,7 @@ StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30 StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } 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 0ebfbca21391..624376769b70 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 @@ -19,7 +19,7 @@ StorageLive(_2); // scope 0 at $DIR/slice_len.rs:+1:5: +1:30 StorageLive(_3); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 - _9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 + _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 // mir::Constant // + span: $DIR/slice_len.rs:5:6: 5:19 // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff index 297836798cbc..c353c375aa96 100644 --- a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff +++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff @@ -28,7 +28,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 - _14 = const main::promoted[0]; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 + _14 = const _; // scope 0 at $DIR/derefer_complex_case.rs:+1:17: +1:26 // mir::Constant // + span: $DIR/derefer_complex_case.rs:6:17: 6:26 // + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) } diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff index 7017413ad38a..7e017373b441 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff @@ -38,7 +38,7 @@ + StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43 + StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -+ _9 = const alloc::raw_vec::RawVec::::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ++ _9 = const _; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL // mir::Constant - // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 - // + user_ty: UserType(1) 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 d5410d3afd4a..cabc1a92024f 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 @@ -32,7 +32,7 @@ fn bar() -> bool { _2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6 StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 - _10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 + _10 = const _; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 // mir::Constant // + span: $DIR/inline-retag.rs:12:7: 12:9 // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) } @@ -43,7 +43,7 @@ fn bar() -> bool { Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9 StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 - _9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 + _9 = const _; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14 // mir::Constant // + span: $DIR/inline-retag.rs:12:11: 12:14 // + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) } diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff index ac7fe31f3b39..76d8d9396255 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff @@ -87,7 +87,7 @@ StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = const _; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } diff --git a/src/test/mir-opt/issue_99325.main.mir_map.0.mir b/src/test/mir-opt/issue_99325.main.mir_map.0.mir index 5bca9f0ea989..8659ddfdb00c 100644 --- a/src/test/mir-opt/issue_99325.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_99325.main.mir_map.0.mir @@ -2,7 +2,7 @@ | User Type Annotations | 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: None }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [], promoted: () }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15 diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff index f92ff9faf979..a648e5d672dc 100644 --- a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff @@ -44,7 +44,7 @@ StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45 StorageLive(_6); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 - _19 = const discriminant::::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 + _19 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44 // mir::Constant // + span: $DIR/lower_intrinsics.rs:50:42: 50:44 // + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) } @@ -65,7 +65,7 @@ StorageLive(_9); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46 StorageLive(_10); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 - _18 = const discriminant::::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 + _18 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45 // mir::Constant // + span: $DIR/lower_intrinsics.rs:51:42: 51:45 // + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) } @@ -86,7 +86,7 @@ StorageLive(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48 StorageLive(_14); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 - _17 = const discriminant::::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 + _17 = const _; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47 // mir::Constant // + span: $DIR/lower_intrinsics.rs:52:42: 52:47 // + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) } 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 c05ed00f7539..b193a8d76fcb 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 @@ -51,7 +51,7 @@ fn full_tested_match() -> () { bb5: { StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 - _11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 + _11 = const _; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15 // mir::Constant // + span: $DIR/match_false_edges.rs:14:14: 14:15 // + literal: Const { ty: &Option, val: Unevaluated(full_tested_match, [], Some(promoted[0])) } diff --git a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir index 8ea61533d073..899bb67fb3ae 100644 --- a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir @@ -121,7 +121,7 @@ fn array_casts() -> () { _14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _35 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) } 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 e4a06554f1a6..7212de52fc37 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 @@ -142,7 +142,7 @@ fn main() -> () { Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24 StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23 StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23 - _28 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:+18:21: +18:23 + _28 = const _; // scope 7 at $DIR/retag.rs:+18:21: +18:23 // mir::Constant // + span: $DIR/retag.rs:48:21: 48:23 // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }