From 72fee14aced19a7036444f66118148dd55486411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 20 Nov 2025 16:30:19 +0100 Subject: [PATCH] Ensure type is monomorphic enough before evaluating size_of / align_of. --- .../src/interpret/intrinsics.rs | 2 ++ .../dependence_lint.full.stderr | 17 ++++++++++----- .../generic_const_exprs/dependence_lint.rs | 4 ++-- .../min_const_generics/complex-expression.rs | 4 ++-- .../complex-expression.stderr | 16 +++++++++----- .../const-evaluatable-unchecked.rs | 6 +++--- .../const-evaluatable-unchecked.stderr | 17 ++++++++++----- tests/ui/consts/size-align-monomorphic.rs | 21 +++++++++++++++++++ 8 files changed, 65 insertions(+), 22 deletions(-) create mode 100644 tests/ui/consts/size-align-monomorphic.rs diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index c6c93ed7f69ec..d7b475c688a12 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -187,6 +187,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } sym::size_of => { let tp_ty = instance.args.type_at(0); + ensure_monomorphic_enough(tcx, tp_ty)?; let layout = self.layout_of(tp_ty)?; if !layout.is_sized() { span_bug!(self.cur_span(), "unsized type for `size_of`"); @@ -196,6 +197,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } sym::align_of => { let tp_ty = instance.args.type_at(0); + ensure_monomorphic_enough(tcx, tp_ty)?; let layout = self.layout_of(tp_ty)?; if !layout.is_sized() { span_bug!(self.cur_span(), "unsized type for `align_of`"); diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr index 23e126d870205..94776f602c52f 100644 --- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr @@ -16,15 +16,21 @@ LL | let _: [u8; if true { size_of::() } else { 3 }]; // error on stable, = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -warning: cannot use constants which depend on generic parameters in types +error: constant expression depends on a generic parameter --> $DIR/dependence_lint.rs:10:9 | LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs` | ^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #76200 - = note: `#[warn(const_evaluatable_unchecked)]` (part of `#[warn(future_incompatible)]`) on by default + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/dependence_lint.rs:10:5 + | +LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes warning: cannot use constants which depend on generic parameters in types --> $DIR/dependence_lint.rs:18:9 @@ -34,6 +40,7 @@ LL | [0; if false { size_of::() } else { 3 }]; // lint on stable, error w | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 + = note: `#[warn(const_evaluatable_unchecked)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs b/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs index 6b3c8f84be3d1..f5d20a7cfb8e7 100644 --- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs +++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.rs @@ -10,8 +10,8 @@ fn foo() { [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs` //[gce]~^ ERROR unconstrained //[gce]~| ERROR unconstrained generic constant - //[full]~^^^ WARNING cannot use constants - //[full]~| WARNING this was previously accepted + //[full]~^^^ ERROR constant expression depends on a generic parameter + //[full]~| ERROR constant expression depends on a generic parameter let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce //[full]~^ ERROR generic parameters may not be used //[gce]~^^ ERROR unconstrained generic diff --git a/tests/ui/const-generics/min_const_generics/complex-expression.rs b/tests/ui/const-generics/min_const_generics/complex-expression.rs index ef2cbfa73adae..972668aac062f 100644 --- a/tests/ui/const-generics/min_const_generics/complex-expression.rs +++ b/tests/ui/const-generics/min_const_generics/complex-expression.rs @@ -36,8 +36,8 @@ fn break_ty2() { fn break_ty3() { let _ = [0; size_of::<*mut T>() + 1]; - //~^ WARN cannot use constants which depend on generic parameters in types - //~| WARN this was previously accepted by the compiler but is being phased out + //~^ ERROR constant expression depends on a generic parameter + //~| ERROR constant expression depends on a generic parameter } diff --git a/tests/ui/const-generics/min_const_generics/complex-expression.stderr b/tests/ui/const-generics/min_const_generics/complex-expression.stderr index ed3fa840cdfed..e13e9cc7716b9 100644 --- a/tests/ui/const-generics/min_const_generics/complex-expression.stderr +++ b/tests/ui/const-generics/min_const_generics/complex-expression.stderr @@ -61,15 +61,21 @@ LL | let _: [u8; size_of::<*mut T>() + 1]; = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -warning: cannot use constants which depend on generic parameters in types +error: constant expression depends on a generic parameter --> $DIR/complex-expression.rs:38:17 | LL | let _ = [0; size_of::<*mut T>() + 1]; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #76200 - = note: `#[warn(const_evaluatable_unchecked)]` (part of `#[warn(future_incompatible)]`) on by default + = note: this may fail depending on what value the parameter takes -error: aborting due to 7 previous errors; 1 warning emitted +error: constant expression depends on a generic parameter + --> $DIR/complex-expression.rs:38:13 + | +LL | let _ = [0; size_of::<*mut T>() + 1]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 9 previous errors diff --git a/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs b/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs index a3235e3878ae2..84f5d208d63b6 100644 --- a/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs +++ b/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs @@ -1,11 +1,11 @@ -//@ check-pass +// //@ compile-flags: -Zdeduplicate-diagnostics=yes #![allow(dead_code)] fn foo() { [0; std::mem::size_of::<*mut T>()]; - //~^ WARN cannot use constants which depend on generic parameters in types - //~| WARN this was previously accepted by the compiler but is being phased out + //~^ ERROR constant expression depends on a generic parameter + //~| ERROR constant expression depends on a generic parameter } struct Foo(T); diff --git a/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr index cf72c0aa0df75..24278b2f03ade 100644 --- a/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr +++ b/tests/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr @@ -1,12 +1,18 @@ -warning: cannot use constants which depend on generic parameters in types +error: constant expression depends on a generic parameter --> $DIR/const-evaluatable-unchecked.rs:6:9 | LL | [0; std::mem::size_of::<*mut T>()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #76200 - = note: `#[warn(const_evaluatable_unchecked)]` (part of `#[warn(future_incompatible)]`) on by default + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/const-evaluatable-unchecked.rs:6:5 + | +LL | [0; std::mem::size_of::<*mut T>()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes warning: cannot use constants which depend on generic parameters in types --> $DIR/const-evaluatable-unchecked.rs:17:21 @@ -16,6 +22,7 @@ LL | let _ = [0; Self::ASSOC]; | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 + = note: `#[warn(const_evaluatable_unchecked)]` (part of `#[warn(future_incompatible)]`) on by default warning: cannot use constants which depend on generic parameters in types --> $DIR/const-evaluatable-unchecked.rs:29:21 @@ -26,5 +33,5 @@ LL | let _ = [0; Self::ASSOC]; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 -warning: 3 warnings emitted +error: aborting due to 2 previous errors; 2 warnings emitted diff --git a/tests/ui/consts/size-align-monomorphic.rs b/tests/ui/consts/size-align-monomorphic.rs new file mode 100644 index 0000000000000..ba09bc92e1979 --- /dev/null +++ b/tests/ui/consts/size-align-monomorphic.rs @@ -0,0 +1,21 @@ +// Regression test for #149081. Check that an attempt to evaluate size_of / align_of intrinsics +// during an optimization, when type parameter is not monomorphic enough, doesn't lead to a +// compilation failure. +// +//@compile-flags: --crate-type=lib -O +//@build-pass + +pub fn size_align_of, U>() -> (usize, usize) { + let a = const { std::mem::size_of::>() }; + let b = const { std::mem::align_of::>() }; + (a, b) +} + +pub struct Wrapper { + pub assoc2: ::Assoc, + pub value: T, +} + +pub trait WithAssoc { + type Assoc: WithAssoc; +}