From 37244a7c9e532012719cd73b0314e419979c1ad9 Mon Sep 17 00:00:00 2001 From: cijiugechu Date: Sun, 17 May 2026 21:21:44 +0800 Subject: [PATCH] evaluate Unevaluated const inside Const::Ty in valtree conversion --- .../rustc_codegen_ssa/src/mir/constant.rs | 6 +++-- compiler/rustc_mir_build/src/builder/scope.rs | 3 ++- .../type-const-const-continue-ice.rs | 25 +++++++++++++++++++ .../type-const-const-continue-ice.stderr | 8 ++++++ 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 tests/ui/loop-match/type-const-const-continue-ice.rs create mode 100644 tests/ui/loop-match/type-const-const-continue-ice.stderr diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index abdac4c7c3721..0b31320f441c9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -29,8 +29,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } /// This is a convenience helper for `immediate_const_vector`. It has the precondition - /// that the given `constant` is an `Const::Unevaluated` and must be convertible to - /// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip. + /// that the given `constant` is a `Const::Unevaluated`, or a `Const::Ty` containing a + /// `ty::ConstKind::Value` or `ty::ConstKind::Unevaluated`, and must be convertible to a + /// `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip. /// /// Note that this function is cursed, since usually MIR consts should not be evaluated to /// valtrees! @@ -44,6 +45,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // A constant that came from a const generic but was then used as an argument to // old-style simd_shuffle (passing as argument instead of as a generic param). ty::ConstKind::Value(cv) => return Ok(Ok(cv.valtree)), + ty::ConstKind::Unevaluated(uv) => uv, other => span_bug!(constant.span, "{other:#?}"), }, // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 3343bec30caf5..a187ea6252b72 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -847,10 +847,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert!(!constant.const_.ty().has_param()); let (uv, ty) = match constant.const_ { mir::Const::Unevaluated(uv, ty) => (uv.shrink(), ty), - mir::Const::Ty(_, c) => match c.kind() { + mir::Const::Ty(ty, c) => match c.kind() { // A constant that came from a const generic but was then used as an argument to // old-style simd_shuffle (passing as argument instead of as a generic param). ty::ConstKind::Value(cv) => return Ok((cv.valtree, cv.ty)), + ty::ConstKind::Unevaluated(uv) => (uv, ty), other => span_bug!(constant.span, "{other:#?}"), }, mir::Const::Val(mir::ConstValue::Scalar(mir::interpret::Scalar::Int(val)), ty) => { diff --git a/tests/ui/loop-match/type-const-const-continue-ice.rs b/tests/ui/loop-match/type-const-const-continue-ice.rs new file mode 100644 index 0000000000000..3e2c4027aec2c --- /dev/null +++ b/tests/ui/loop-match/type-const-const-continue-ice.rs @@ -0,0 +1,25 @@ +// Regression test for + +#![feature(min_generic_const_args)] +#![feature(loop_match)] + +trait T { + type const N: usize; + fn a() { + let mut s; + #[loop_match] + loop { + s = 'b: { + match s { + _ => { + #[const_continue] + break 'b Self::N + //~^ ERROR could not determine the target branch for this `#[const_continue]` + } + } + } + } + } +} + +fn main() {} diff --git a/tests/ui/loop-match/type-const-const-continue-ice.stderr b/tests/ui/loop-match/type-const-const-continue-ice.stderr new file mode 100644 index 0000000000000..ca44c46265da0 --- /dev/null +++ b/tests/ui/loop-match/type-const-const-continue-ice.stderr @@ -0,0 +1,8 @@ +error: could not determine the target branch for this `#[const_continue]` + --> $DIR/type-const-const-continue-ice.rs:16:34 + | +LL | break 'b Self::N + | ^^^^^^^ this value is too generic + +error: aborting due to 1 previous error +