diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 9784de1fffc..a5f00d0aff2 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -585,7 +585,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { uneval: &ty::Unevaluated<'tcx>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { let instance = self.resolve(uneval.def, uneval.substs)?; - Ok(self.eval_to_allocation(GlobalId { instance, promoted: None })?.into()) + Ok(self.eval_to_allocation(GlobalId { instance, promoted: uneval.promoted })?.into()) } pub fn mir_const_to_op( 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 fce799d47ec..23a013980be 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -346,32 +346,41 @@ 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. + let uneval = match constant.literal { + ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Unevaluated(_)) => { + let ty::ConstKind::Unevaluated(uv) = ct.kind() else { unreachable!() }; - // Don't peek inside trait associated constants. - if 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) - }; + Some(uv.expand()) + } + ConstantKind::Ty(_) => None, + ConstantKind::Unevaluated(uv, _) => Some(uv), + ConstantKind::Val(..) => None, + }; - if !Q::in_qualifs(&qualifs) { - return false; - } + 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); - // Just in case the type is more specific than - // the definition, e.g., impl associated const - // with type parameters, take it into account. + // 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_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index e5aadac8739..022ec6f074d 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -236,7 +236,7 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> { 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, t.try_fold_with(folder)?)) + 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 6a0801cb0dd..4b3ad9cc5da 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_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index d083a3e00b6..b4bda57ba83 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -313,7 +313,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } match constant { - ConstantKind::Ty(_) => constant.super_visit_with(self), + 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]`