From bc7986ec791ded521f3f75ab82645b6be0c39508 Mon Sep 17 00:00:00 2001
From: Nikita Popov
Date: Thu, 18 Sep 2025 17:09:14 +0200
Subject: Add attributes for #[global_allocator] functions
Emit `#[rustc_allocator]` etc. attributes on the functions generated
by the `#[global_allocator]` macro, which will emit LLVM attributes
like `"alloc-family"`. If the module with the global allocator
participates in LTO, this ensures that the attributes typically
emitted on the allocator declarations are not lost if the
definition is imported.
---
tests/codegen-llvm/global-allocator-attributes.rs | 41 +++++++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 tests/codegen-llvm/global-allocator-attributes.rs
(limited to 'tests')
diff --git a/tests/codegen-llvm/global-allocator-attributes.rs b/tests/codegen-llvm/global-allocator-attributes.rs
new file mode 100644
index 00000000000..472ca772075
--- /dev/null
+++ b/tests/codegen-llvm/global-allocator-attributes.rs
@@ -0,0 +1,41 @@
+//@ compile-flags: -C opt-level=3
+#![crate_type = "lib"]
+
+mod foobar {
+ use std::alloc::{GlobalAlloc, Layout};
+
+ struct Allocator;
+
+ unsafe impl GlobalAlloc for Allocator {
+ unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+ // CHECK-LABEL: ; __rustc::__rust_alloc
+ // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,uninitialized,aligned") allocsize(0){{.*}}
+ // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc(i[[SIZE:[0-9]+]] {{.*}}%size, i[[SIZE]] allocalign{{.*}} %align)
+ panic!()
+ }
+
+ unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+ // CHECK-LABEL: ; __rustc::__rust_dealloc
+ // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("free"){{.*}}
+ // CHECK-NEXT: define{{.*}} void @{{.*}}__rust_dealloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] {{.*}} %align)
+ panic!()
+ }
+
+ unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+ // CHECK-LABEL: ; __rustc::__rust_realloc
+ // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("realloc,aligned") allocsize(3){{.*}}
+ // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_realloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align, i[[SIZE]] {{.*}} %new_size)
+ panic!()
+ }
+
+ unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+ // CHECK-LABEL: ; __rustc::__rust_alloc_zeroed
+ // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,zeroed,aligned") allocsize(0){{.*}}
+ // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc_zeroed(i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align)
+ panic!()
+ }
+ }
+
+ #[global_allocator]
+ static GLOBAL: Allocator = Allocator;
+}
--
cgit 1.4.1-3-g733a5
From f5c6c9542ecfab74e654f9b7f1150d486560ae43 Mon Sep 17 00:00:00 2001
From: Caleb Zulawski
Date: Tue, 16 Sep 2025 02:23:24 -0400
Subject: Add an attribute to check the number of lanes in a SIMD vector after
monomorphization
Unify zero-length and oversized SIMD errors
---
.../src/attributes/crate_level.rs | 36 ---------------------
.../src/attributes/rustc_internal.rs | 18 +++++++++++
compiler/rustc_attr_parsing/src/attributes/util.rs | 37 +++++++++++++++++++++-
compiler/rustc_attr_parsing/src/context.rs | 3 +-
compiler/rustc_codegen_cranelift/src/common.rs | 9 ++++--
compiler/rustc_codegen_cranelift/src/global_asm.rs | 5 ++-
compiler/rustc_codegen_gcc/src/context.rs | 9 ++++--
compiler/rustc_codegen_llvm/src/context.rs | 11 +++++--
compiler/rustc_feature/src/builtin_attrs.rs | 6 ++++
compiler/rustc_hir/src/attrs/data_structures.rs | 3 ++
compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 +
.../rustc_hir_analysis/src/hir_ty_lowering/cmse.rs | 1 +
compiler/rustc_middle/messages.ftl | 6 ++++
compiler/rustc_middle/src/error.rs | 6 ++++
compiler/rustc_middle/src/ty/layout.rs | 26 +++++++++++++++
compiler/rustc_passes/src/check_attr.rs | 1 +
compiler/rustc_span/src/symbol.rs | 1 +
compiler/rustc_transmute/src/layout/tree.rs | 1 +
compiler/rustc_ty_utils/src/errors.rs | 13 --------
compiler/rustc_ty_utils/src/layout.rs | 26 ++++++++++++---
src/librustdoc/html/templates/type_layout.html | 5 +++
tests/ui/simd/auxiliary/simd-lane-limit.rs | 5 +++
tests/ui/simd/monomorphize-too-long.rs | 4 +--
tests/ui/simd/monomorphize-too-long.stderr | 6 +++-
tests/ui/simd/monomorphize-zero-length.rs | 4 +--
tests/ui/simd/monomorphize-zero-length.stderr | 6 +++-
tests/ui/simd/simd-lane-limit-err-npow2.rs | 12 +++++++
tests/ui/simd/simd-lane-limit-err-npow2.stderr | 8 +++++
tests/ui/simd/simd-lane-limit-err.rs | 11 +++++++
tests/ui/simd/simd-lane-limit-err.stderr | 8 +++++
tests/ui/simd/simd-lane-limit-ok.rs | 14 ++++++++
.../ui/simd/type-generic-monomorphisation-empty.rs | 4 +--
.../type-generic-monomorphisation-empty.stderr | 6 +++-
.../type-generic-monomorphisation-oversized.rs | 5 ++-
.../type-generic-monomorphisation-oversized.stderr | 6 +++-
35 files changed, 245 insertions(+), 78 deletions(-)
create mode 100644 tests/ui/simd/auxiliary/simd-lane-limit.rs
create mode 100644 tests/ui/simd/simd-lane-limit-err-npow2.rs
create mode 100644 tests/ui/simd/simd-lane-limit-err-npow2.stderr
create mode 100644 tests/ui/simd/simd-lane-limit-err.rs
create mode 100644 tests/ui/simd/simd-lane-limit-err.stderr
create mode 100644 tests/ui/simd/simd-lane-limit-ok.rs
(limited to 'tests')
diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
index 4611de44459..00edafecd9a 100644
--- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
@@ -1,40 +1,4 @@
-use std::num::IntErrorKind;
-
-use rustc_hir::limit::Limit;
-
use super::prelude::*;
-use crate::session_diagnostics::LimitInvalid;
-
-impl AcceptContext<'_, '_, S> {
- fn parse_limit_int(&self, nv: &NameValueParser) -> Option {
- let Some(limit) = nv.value_as_str() else {
- self.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
- return None;
- };
-
- let error_str = match limit.as_str().parse() {
- Ok(i) => return Some(Limit::new(i)),
- Err(e) => match e.kind() {
- IntErrorKind::PosOverflow => "`limit` is too large",
- IntErrorKind::Empty => "`limit` must be a non-negative integer",
- IntErrorKind::InvalidDigit => "not a valid integer",
- IntErrorKind::NegOverflow => {
- panic!(
- "`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
- )
- }
- IntErrorKind::Zero => {
- panic!("zero is a valid `limit` so should have returned Ok() when parsing")
- }
- kind => panic!("unimplemented IntErrorKind variant: {:?}", kind),
- },
- };
-
- self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str });
-
- None
- }
-}
pub(crate) struct CrateNameParser;
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
index a995549fc7c..cf2f5c6c790 100644
--- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
@@ -49,3 +49,21 @@ impl SingleAttributeParser for RustcObjectLifetimeDefaultParser {
Some(AttributeKind::RustcObjectLifetimeDefault)
}
}
+
+pub(crate) struct RustcSimdMonomorphizeLaneLimitParser;
+
+impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser {
+ const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit];
+ const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
+ const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
+
+ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option {
+ let ArgParser::NameValue(nv) = args else {
+ cx.expected_name_value(cx.attr_span, None);
+ return None;
+ };
+ Some(AttributeKind::RustcSimdMonomorphizeLaneLimit(cx.parse_limit_int(nv)?))
+ }
+}
diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs
index 77e8c32e59d..62b72798e96 100644
--- a/compiler/rustc_attr_parsing/src/attributes/util.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/util.rs
@@ -1,11 +1,15 @@
+use std::num::IntErrorKind;
+
use rustc_ast::LitKind;
use rustc_ast::attr::AttributeExt;
use rustc_feature::is_builtin_attr_name;
use rustc_hir::RustcVersion;
+use rustc_hir::limit::Limit;
use rustc_span::{Symbol, sym};
use crate::context::{AcceptContext, Stage};
-use crate::parser::ArgParser;
+use crate::parser::{ArgParser, NameValueParser};
+use crate::session_diagnostics::LimitInvalid;
/// Parse a rustc version number written inside string literal in an attribute,
/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are
@@ -85,3 +89,34 @@ pub(crate) fn parse_single_integer(
};
Some(num.0)
}
+
+impl AcceptContext<'_, '_, S> {
+ pub(crate) fn parse_limit_int(&self, nv: &NameValueParser) -> Option {
+ let Some(limit) = nv.value_as_str() else {
+ self.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ return None;
+ };
+
+ let error_str = match limit.as_str().parse() {
+ Ok(i) => return Some(Limit::new(i)),
+ Err(e) => match e.kind() {
+ IntErrorKind::PosOverflow => "`limit` is too large",
+ IntErrorKind::Empty => "`limit` must be a non-negative integer",
+ IntErrorKind::InvalidDigit => "not a valid integer",
+ IntErrorKind::NegOverflow => {
+ panic!(
+ "`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
+ )
+ }
+ IntErrorKind::Zero => {
+ panic!("zero is a valid `limit` so should have returned Ok() when parsing")
+ }
+ kind => panic!("unimplemented IntErrorKind variant: {:?}", kind),
+ },
+ };
+
+ self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str });
+
+ None
+ }
+}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index d7998048be5..72fe269b135 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -53,7 +53,7 @@ use crate::attributes::prototype::CustomMirParser;
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
use crate::attributes::rustc_internal::{
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
- RustcObjectLifetimeDefaultParser,
+ RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
};
use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{
@@ -195,6 +195,7 @@ attribute_parsers!(
Single,
Single,
Single,
+ Single,
Single,
Single,
Single,
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index 2fbe5c02802..81b1814605a 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -439,7 +439,10 @@ pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
impl<'tcx> LayoutOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
- if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
+ if let LayoutError::SizeOverflow(_)
+ | LayoutError::InvalidSimd { .. }
+ | LayoutError::ReferencesError(_) = err
+ {
self.0.sess.dcx().span_fatal(span, err.to_string())
} else {
self.0
@@ -458,7 +461,9 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> {
span: Span,
fn_abi_request: FnAbiRequest<'tcx>,
) -> ! {
- if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
+ if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) =
+ err
+ {
self.0.sess.dcx().emit_fatal(Spanned { span, node: err })
} else {
match fn_abi_request {
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs
index 203b443269f..1306c6aa517 100644
--- a/compiler/rustc_codegen_cranelift/src/global_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -42,7 +42,10 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> {
impl<'tcx> LayoutOfHelpers<'tcx> for GlobalAsmContext<'_, 'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
- if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
+ if let LayoutError::SizeOverflow(_)
+ | LayoutError::InvalidSimd { .. }
+ | LayoutError::ReferencesError(_) = err
+ {
self.tcx.sess.dcx().span_fatal(span, err.to_string())
} else {
self.tcx
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 665cf22ddba..9815fb07eaa 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -529,7 +529,10 @@ impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
- if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
+ if let LayoutError::SizeOverflow(_)
+ | LayoutError::InvalidSimd { .. }
+ | LayoutError::ReferencesError(_) = err
+ {
self.tcx.dcx().emit_fatal(respan(span, err.into_diagnostic()))
} else {
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
@@ -545,7 +548,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
span: Span,
fn_abi_request: FnAbiRequest<'tcx>,
) -> ! {
- if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
+ if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) =
+ err
+ {
self.tcx.dcx().emit_fatal(respan(span, err))
} else {
match fn_abi_request {
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index a69fa54a54a..e4528efaa37 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -991,7 +991,10 @@ impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
- if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
+ if let LayoutError::SizeOverflow(_)
+ | LayoutError::ReferencesError(_)
+ | LayoutError::InvalidSimd { .. } = err
+ {
self.tcx.dcx().emit_fatal(Spanned { span, node: err.into_diagnostic() })
} else {
self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
@@ -1008,7 +1011,11 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
fn_abi_request: FnAbiRequest<'tcx>,
) -> ! {
match err {
- FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::Cycle(_)) => {
+ FnAbiError::Layout(
+ LayoutError::SizeOverflow(_)
+ | LayoutError::Cycle(_)
+ | LayoutError::InvalidSimd { .. },
+ ) => {
self.tcx.dcx().emit_fatal(Spanned { span, node: err });
}
_ => match fn_abi_request {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 129ab7eccb5..0d890b57de0 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -1203,6 +1203,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
niche optimizations in the standard library",
),
+ rustc_attr!(
+ rustc_simd_monomorphize_lane_limit, Normal, template!(NameValueStr: "N"), ErrorFollowing,
+ EncodeCrossCrate::Yes,
+ "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \
+ for better error messages",
+ ),
rustc_attr!(
rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes,
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index ea11a99efbc..80cb6417684 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -642,6 +642,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_object_lifetime_default]`.
RustcObjectLifetimeDefault,
+ /// Represents `#[rustc_simd_monomorphize_lane_limit = "N"]`.
+ RustcSimdMonomorphizeLaneLimit(Limit),
+
/// Represents `#[sanitize]`
///
/// the on set and off set are distjoint since there's a third option: unset.
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
index 55521c15854..968ea668efe 100644
--- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
+++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -85,6 +85,7 @@ impl AttributeKind {
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
RustcObjectLifetimeDefault => No,
+ RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate
Sanitize { .. } => No,
ShouldPanic { .. } => No,
SkipDuringMethodDispatch { .. } => No,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index 5088c63702e..76b0ce985f0 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -213,6 +213,7 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError
}
Unknown(..)
| SizeOverflow(..)
+ | InvalidSimd { .. }
| NormalizationFailure(..)
| ReferencesError(..)
| Cycle(..) => {
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index 279ab9a9d8f..82f3df8da3b 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -98,6 +98,12 @@ middle_layout_references_error =
middle_layout_size_overflow =
values of the type `{$ty}` are too big for the target architecture
+middle_layout_simd_too_many =
+ the SIMD type `{$ty}` has more elements than the limit {$max_lanes}
+
+middle_layout_simd_zero_length =
+ the SIMD type `{$ty}` has zero elements
+
middle_layout_too_generic = the type `{$ty}` does not have a fixed layout
middle_layout_unknown =
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index dad402ec696..e15da827bda 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -141,6 +141,12 @@ pub enum LayoutError<'tcx> {
#[diag(middle_layout_size_overflow)]
Overflow { ty: Ty<'tcx> },
+ #[diag(middle_layout_simd_too_many)]
+ SimdTooManyLanes { ty: Ty<'tcx>, max_lanes: u64 },
+
+ #[diag(middle_layout_simd_zero_length)]
+ SimdZeroLength { ty: Ty<'tcx> },
+
#[diag(middle_layout_normalization_failure)]
NormalizationFailure { ty: Ty<'tcx>, failure_ty: String },
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 2114d080dfa..47e561d9d3c 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -217,6 +217,15 @@ impl fmt::Display for ValidityRequirement {
}
}
+#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
+pub enum SimdLayoutError {
+ /// The vector has 0 lanes.
+ ZeroLength,
+ /// The vector has more lanes than supported or permitted by
+ /// #\[rustc_simd_monomorphize_lane_limit\].
+ TooManyLanes(u64),
+}
+
#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
pub enum LayoutError<'tcx> {
/// A type doesn't have a sensible layout.
@@ -229,6 +238,8 @@ pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
/// The size of a type exceeds [`TargetDataLayout::obj_size_bound`].
SizeOverflow(Ty<'tcx>),
+ /// A SIMD vector has invalid layout, such as zero-length or too many lanes.
+ InvalidSimd { ty: Ty<'tcx>, kind: SimdLayoutError },
/// The layout can vary due to a generic parameter.
///
/// Unlike `Unknown`, this variant is a "soft" error and indicates that the layout
@@ -256,6 +267,10 @@ impl<'tcx> LayoutError<'tcx> {
match self {
Unknown(_) => middle_layout_unknown,
SizeOverflow(_) => middle_layout_size_overflow,
+ InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => {
+ middle_layout_simd_too_many
+ }
+ InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => middle_layout_simd_zero_length,
TooGeneric(_) => middle_layout_too_generic,
NormalizationFailure(_, _) => middle_layout_normalization_failure,
Cycle(_) => middle_layout_cycle,
@@ -270,6 +285,10 @@ impl<'tcx> LayoutError<'tcx> {
match self {
Unknown(ty) => E::Unknown { ty },
SizeOverflow(ty) => E::Overflow { ty },
+ InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) } => {
+ E::SimdTooManyLanes { ty, max_lanes }
+ }
+ InvalidSimd { ty, kind: SimdLayoutError::ZeroLength } => E::SimdZeroLength { ty },
TooGeneric(ty) => E::TooGeneric { ty },
NormalizationFailure(ty, e) => {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
@@ -292,6 +311,12 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
LayoutError::SizeOverflow(ty) => {
write!(f, "values of the type `{ty}` are too big for the target architecture")
}
+ LayoutError::InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) } => {
+ write!(f, "the SIMD type `{ty}` has more elements than the limit {max_lanes}")
+ }
+ LayoutError::InvalidSimd { ty, kind: SimdLayoutError::ZeroLength } => {
+ write!(f, "the SIMD type `{ty}` has zero elements")
+ }
LayoutError::NormalizationFailure(t, e) => write!(
f,
"unable to determine layout for `{}` because `{}` cannot be normalized",
@@ -373,6 +398,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
e @ LayoutError::Cycle(_)
| e @ LayoutError::Unknown(_)
| e @ LayoutError::SizeOverflow(_)
+ | e @ LayoutError::InvalidSimd { .. }
| e @ LayoutError::NormalizationFailure(..)
| e @ LayoutError::ReferencesError(_),
) => return Err(e),
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 2562d2e0b83..cabf2819741 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -254,6 +254,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::MacroEscape( .. )
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
| AttributeKind::RustcLayoutScalarValidRangeEnd(..)
+ | AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
| AttributeKind::ExportStable
| AttributeKind::FfiConst(..)
| AttributeKind::UnstableFeatureBound(..)
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index cdb0b5b58da..92a1fad4755 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1937,6 +1937,7 @@ symbols! {
rustc_regions,
rustc_reservation_impl,
rustc_serialize,
+ rustc_simd_monomorphize_lane_limit,
rustc_skip_during_method_dispatch,
rustc_specialization_trait,
rustc_std_internal_symbol,
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index d7ea26a2ab1..a02e8ecf613 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -279,6 +279,7 @@ pub(crate) mod rustc {
LayoutError::Unknown(..)
| LayoutError::ReferencesError(..)
| LayoutError::TooGeneric(..)
+ | LayoutError::InvalidSimd { .. }
| LayoutError::NormalizationFailure(..) => Self::UnknownLayout,
LayoutError::SizeOverflow(..) => Self::SizeOverflow,
LayoutError::Cycle(err) => Self::TypeError(*err),
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
index 0298e7e0e95..f92c405242c 100644
--- a/compiler/rustc_ty_utils/src/errors.rs
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -78,19 +78,6 @@ pub(crate) struct UnexpectedFnPtrAssociatedItem {
pub span: Span,
}
-#[derive(Diagnostic)]
-#[diag(ty_utils_zero_length_simd_type)]
-pub(crate) struct ZeroLengthSimdType<'tcx> {
- pub ty: Ty<'tcx>,
-}
-
-#[derive(Diagnostic)]
-#[diag(ty_utils_oversized_simd_type)]
-pub(crate) struct OversizedSimdType<'tcx> {
- pub ty: Ty<'tcx>,
- pub max_lanes: u64,
-}
-
#[derive(Diagnostic)]
#[diag(ty_utils_non_primitive_simd_type)]
pub(crate) struct NonPrimitiveSimdType<'tcx> {
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 79f7e228e2a..5c4451ce264 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -7,11 +7,13 @@ use rustc_abi::{
VariantIdx, Variants, WrappingRange,
};
use rustc_hashes::Hash64;
+use rustc_hir::attrs::AttributeKind;
+use rustc_hir::find_attr;
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{
- FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout,
+ FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, SimdLayoutError, TyAndLayout,
};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{
@@ -22,7 +24,7 @@ use rustc_span::{Symbol, sym};
use tracing::{debug, instrument};
use {rustc_abi as abi, rustc_hir as hir};
-use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType};
+use crate::errors::NonPrimitiveSimdType;
mod invariant;
@@ -120,11 +122,11 @@ fn map_error<'tcx>(
}
LayoutCalculatorError::ZeroLengthSimdType => {
// Can't be caught in typeck if the array length is generic.
- cx.tcx().dcx().emit_fatal(ZeroLengthSimdType { ty })
+ LayoutError::InvalidSimd { ty, kind: SimdLayoutError::ZeroLength }
}
LayoutCalculatorError::OversizedSimdType { max_lanes } => {
// Can't be caught in typeck if the array length is generic.
- cx.tcx().dcx().emit_fatal(OversizedSimdType { ty, max_lanes })
+ LayoutError::InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(max_lanes) }
}
LayoutCalculatorError::NonPrimitiveSimdType(field) => {
// This error isn't caught in typeck, e.g., if
@@ -561,6 +563,22 @@ fn layout_of_uncached<'tcx>(
let e_ly = cx.layout_of(e_ty)?;
+ // Check for the rustc_simd_monomorphize_lane_limit attribute and check the lane limit
+ if let Some(limit) = find_attr!(
+ tcx.get_all_attrs(def.did()),
+ AttributeKind::RustcSimdMonomorphizeLaneLimit(limit) => limit
+ ) {
+ if !limit.value_within_limit(e_len as usize) {
+ return Err(map_error(
+ &cx,
+ ty,
+ rustc_abi::LayoutCalculatorError::OversizedSimdType {
+ max_lanes: limit.0 as u64,
+ },
+ ));
+ }
+ }
+
map_layout(cx.calc.simd_type(e_ly, e_len, def.repr().packed()))?
}
diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html
index 0034552bdd3..49153d58fe9 100644
--- a/src/librustdoc/html/templates/type_layout.html
+++ b/src/librustdoc/html/templates/type_layout.html
@@ -65,5 +65,10 @@
Note: Encountered an error during type layout; {#+ #}
the type's layout depended on the type's layout itself. {# #}
+ {% when Err(LayoutError::InvalidSimd {..}) %}
+ {# #}
+ Note: Encountered an error during type layout; {#+ #}
+ the vector type had zero elements or too many elements. {# #}
+
{% endmatch %}
{# #}
diff --git a/tests/ui/simd/auxiliary/simd-lane-limit.rs b/tests/ui/simd/auxiliary/simd-lane-limit.rs
new file mode 100644
index 00000000000..dde6b880c62
--- /dev/null
+++ b/tests/ui/simd/auxiliary/simd-lane-limit.rs
@@ -0,0 +1,5 @@
+#![feature(rustc_attrs, repr_simd)]
+
+#[repr(simd, packed)]
+#[rustc_simd_monomorphize_lane_limit = "8"]
+pub struct Simd(pub [T; N]);
diff --git a/tests/ui/simd/monomorphize-too-long.rs b/tests/ui/simd/monomorphize-too-long.rs
index 4fac987b0b5..9c837415191 100644
--- a/tests/ui/simd/monomorphize-too-long.rs
+++ b/tests/ui/simd/monomorphize-too-long.rs
@@ -6,7 +6,5 @@
struct Simd([T; N]);
fn main() {
- let _too_big = Simd([1_u16; 54321]);
+ let _too_big = Simd([1_u16; 54321]); //~ ERROR the SIMD type `Simd` has more elements than the limit 32768
}
-
-//~? ERROR monomorphising SIMD type `Simd` of length greater than 32768
diff --git a/tests/ui/simd/monomorphize-too-long.stderr b/tests/ui/simd/monomorphize-too-long.stderr
index 978eef307ab..71bc78ef5c9 100644
--- a/tests/ui/simd/monomorphize-too-long.stderr
+++ b/tests/ui/simd/monomorphize-too-long.stderr
@@ -1,4 +1,8 @@
-error: monomorphising SIMD type `Simd` of length greater than 32768
+error: the SIMD type `Simd` has more elements than the limit 32768
+ --> $DIR/monomorphize-too-long.rs:9:9
+ |
+LL | let _too_big = Simd([1_u16; 54321]);
+ | ^^^^^^^^
error: aborting due to 1 previous error
diff --git a/tests/ui/simd/monomorphize-zero-length.rs b/tests/ui/simd/monomorphize-zero-length.rs
index d38870c572d..f956197a61c 100644
--- a/tests/ui/simd/monomorphize-zero-length.rs
+++ b/tests/ui/simd/monomorphize-zero-length.rs
@@ -6,7 +6,5 @@
struct Simd([T; N]);
fn main() {
- let _empty = Simd([1.0; 0]);
+ let _empty = Simd([1.0; 0]); //~ ERROR the SIMD type `Simd` has zero elements
}
-
-//~? ERROR monomorphising SIMD type `Simd` of zero length
diff --git a/tests/ui/simd/monomorphize-zero-length.stderr b/tests/ui/simd/monomorphize-zero-length.stderr
index 738c20fe51a..66f26d95c9d 100644
--- a/tests/ui/simd/monomorphize-zero-length.stderr
+++ b/tests/ui/simd/monomorphize-zero-length.stderr
@@ -1,4 +1,8 @@
-error: monomorphising SIMD type `Simd` of zero length
+error: the SIMD type `Simd` has zero elements
+ --> $DIR/monomorphize-zero-length.rs:9:9
+ |
+LL | let _empty = Simd([1.0; 0]);
+ | ^^^^^^
error: aborting due to 1 previous error
diff --git a/tests/ui/simd/simd-lane-limit-err-npow2.rs b/tests/ui/simd/simd-lane-limit-err-npow2.rs
new file mode 100644
index 00000000000..d5c5c92e953
--- /dev/null
+++ b/tests/ui/simd/simd-lane-limit-err-npow2.rs
@@ -0,0 +1,12 @@
+//@ build-fail
+//@ aux-crate:simd=simd-lane-limit.rs
+
+extern crate simd;
+
+use simd::Simd;
+
+fn main() {
+ // test non-power-of-two, since #[repr(simd, packed)] has unusual layout
+ let _x: Simd = Simd([0; 24]);
+ //~^ ERROR the SIMD type `simd::Simd` has more elements than the limit 8
+}
diff --git a/tests/ui/simd/simd-lane-limit-err-npow2.stderr b/tests/ui/simd/simd-lane-limit-err-npow2.stderr
new file mode 100644
index 00000000000..fff26c4c1c1
--- /dev/null
+++ b/tests/ui/simd/simd-lane-limit-err-npow2.stderr
@@ -0,0 +1,8 @@
+error: the SIMD type `simd::Simd` has more elements than the limit 8
+ --> $DIR/simd-lane-limit-err-npow2.rs:10:9
+ |
+LL | let _x: Simd = Simd([0; 24]);
+ | ^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/simd/simd-lane-limit-err.rs b/tests/ui/simd/simd-lane-limit-err.rs
new file mode 100644
index 00000000000..00390bdbdaf
--- /dev/null
+++ b/tests/ui/simd/simd-lane-limit-err.rs
@@ -0,0 +1,11 @@
+//@ build-fail
+//@ aux-crate:simd=simd-lane-limit.rs
+
+extern crate simd;
+
+use simd::Simd;
+
+fn main() {
+ let _x: Simd = Simd([0; 16]);
+ //~^ ERROR the SIMD type `simd::Simd` has more elements than the limit 8
+}
diff --git a/tests/ui/simd/simd-lane-limit-err.stderr b/tests/ui/simd/simd-lane-limit-err.stderr
new file mode 100644
index 00000000000..3f2eaeda2d4
--- /dev/null
+++ b/tests/ui/simd/simd-lane-limit-err.stderr
@@ -0,0 +1,8 @@
+error: the SIMD type `simd::Simd` has more elements than the limit 8
+ --> $DIR/simd-lane-limit-err.rs:9:9
+ |
+LL | let _x: Simd = Simd([0; 16]);
+ | ^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/simd/simd-lane-limit-ok.rs b/tests/ui/simd/simd-lane-limit-ok.rs
new file mode 100644
index 00000000000..52fd3158440
--- /dev/null
+++ b/tests/ui/simd/simd-lane-limit-ok.rs
@@ -0,0 +1,14 @@
+//@ build-pass
+//@ aux-crate:simd=simd-lane-limit.rs
+
+extern crate simd;
+
+use simd::Simd;
+
+fn main() {
+ let _x: Simd = Simd([0; 4]);
+ let _y: Simd = Simd([0; 8]);
+
+ // test non-power-of-two, since #[repr(simd, packed)] has unusual layout
+ let _z: Simd = Simd([0; 6]);
+}
diff --git a/tests/ui/simd/type-generic-monomorphisation-empty.rs b/tests/ui/simd/type-generic-monomorphisation-empty.rs
index c08dc9fe3df..7c43b8914da 100644
--- a/tests/ui/simd/type-generic-monomorphisation-empty.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-empty.rs
@@ -6,7 +6,5 @@
struct Simd([f32; N]);
fn main() {
- let _ = Simd::<0>([]);
+ let _empty = Simd::<0>([]); //~ ERROR the SIMD type `Simd<0>` has zero elements
}
-
-//~? ERROR monomorphising SIMD type `Simd<0>` of zero length
diff --git a/tests/ui/simd/type-generic-monomorphisation-empty.stderr b/tests/ui/simd/type-generic-monomorphisation-empty.stderr
index fc294607ae3..450db7e47db 100644
--- a/tests/ui/simd/type-generic-monomorphisation-empty.stderr
+++ b/tests/ui/simd/type-generic-monomorphisation-empty.stderr
@@ -1,4 +1,8 @@
-error: monomorphising SIMD type `Simd<0>` of zero length
+error: the SIMD type `Simd<0>` has zero elements
+ --> $DIR/type-generic-monomorphisation-empty.rs:9:9
+ |
+LL | let _empty = Simd::<0>([]);
+ | ^^^^^^
error: aborting due to 1 previous error
diff --git a/tests/ui/simd/type-generic-monomorphisation-oversized.rs b/tests/ui/simd/type-generic-monomorphisation-oversized.rs
index efe3480317c..73a1f00e8c7 100644
--- a/tests/ui/simd/type-generic-monomorphisation-oversized.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-oversized.rs
@@ -6,7 +6,6 @@
struct Simd([f32; N]);
fn main() {
- let _ = Simd::<65536>([0.; 65536]);
+ let _x = Simd::<65536>([0.; 65536]);
+ //~^ ERROR the SIMD type `Simd<65536>` has more elements than the limit 32768
}
-
-//~? ERROR monomorphising SIMD type `Simd<65536>` of length greater than 32768
diff --git a/tests/ui/simd/type-generic-monomorphisation-oversized.stderr b/tests/ui/simd/type-generic-monomorphisation-oversized.stderr
index 39ff36799cc..0065049abd6 100644
--- a/tests/ui/simd/type-generic-monomorphisation-oversized.stderr
+++ b/tests/ui/simd/type-generic-monomorphisation-oversized.stderr
@@ -1,4 +1,8 @@
-error: monomorphising SIMD type `Simd<65536>` of length greater than 32768
+error: the SIMD type `Simd<65536>` has more elements than the limit 32768
+ --> $DIR/type-generic-monomorphisation-oversized.rs:9:9
+ |
+LL | let _x = Simd::<65536>([0.; 65536]);
+ | ^^
error: aborting due to 1 previous error
--
cgit 1.4.1-3-g733a5
From a86f14072714fb817a6f60fa20be5a4e875d049f Mon Sep 17 00:00:00 2001
From: Ding Xiang Fei
Date: Tue, 12 Aug 2025 06:39:50 +0800
Subject: do not materialise X in [X; 0] when X is unsizing a const
---
.../rustc_mir_build/src/builder/expr/as_rvalue.rs | 21 ++++++++++++++-
.../no_local_for_coerced_const-issue-143671.rs | 30 ++++++++++++++++++++++
2 files changed, 50 insertions(+), 1 deletion(-)
create mode 100644 tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
(limited to 'tests')
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index a4ef6e92739..d6dc12e5955 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -8,6 +8,7 @@ use rustc_middle::middle::region;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
+use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::{CastTy, mir_cast_kind};
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, Ty, UpvarArgs};
@@ -656,6 +657,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.and(rvalue)
}
+ /// Recursively inspect a THIR expression and probe through unsizing
+ /// operations that can be const-folded today.
+ fn check_constness(&self, mut kind: &'a ExprKind<'tcx>) -> bool {
+ loop {
+ match kind {
+ &ExprKind::PointerCoercion {
+ cast: PointerCoercion::Unsize,
+ source: eid,
+ is_from_as_cast: _,
+ }
+ | &ExprKind::Scope { region_scope: _, lint_level: _, value: eid } => {
+ kind = &self.thir[eid].kind
+ }
+ _ => return matches!(Category::of(&kind), Some(Category::Constant)),
+ }
+ }
+ }
+
fn build_zero_repeat(
&mut self,
mut block: BasicBlock,
@@ -666,7 +685,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let this = self;
let value_expr = &this.thir[value];
let elem_ty = value_expr.ty;
- if let Some(Category::Constant) = Category::of(&value_expr.kind) {
+ if this.check_constness(&value_expr.kind) {
// Repeating a const does nothing
} else {
// For a non-const, we may need to generate an appropriate `Drop`
diff --git a/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
new file mode 100644
index 00000000000..eb814e9723c
--- /dev/null
+++ b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
@@ -0,0 +1,30 @@
+//@ run-pass
+
+#![feature(unsize)]
+#![feature(coerce_unsized)]
+
+use std::fmt::Display;
+use std::marker::Unsize;
+use std::ops::CoerceUnsized;
+
+#[repr(transparent)]
+struct X<'a, T: ?Sized> {
+ f: &'a T,
+}
+
+impl<'a, T: ?Sized> Drop for X<'a, T> {
+ fn drop(&mut self) {
+ panic!()
+ }
+}
+
+impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for X<'a, T> where
+ &'a T: CoerceUnsized<&'a U>
+{
+}
+
+const Y: X<'static, i32> = X { f: &0 };
+
+fn main() {
+ let _: [X<'static, dyn Display>; 0] = [Y; 0];
+}
--
cgit 1.4.1-3-g733a5
From 120162e30ffa92308a6a3a76f2328467fbd10ced Mon Sep 17 00:00:00 2001
From: Ding Xiang Fei
Date: Wed, 13 Aug 2025 02:26:04 +0800
Subject: add test fixture for newly allowed const expr
Signed-off-by: Ding Xiang Fei
Co-authored-by: Theemathas Chirananthavat
---
tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs | 8 ++++++++
1 file changed, 8 insertions(+)
(limited to 'tests')
diff --git a/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
index eb814e9723c..5924809f34c 100644
--- a/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
+++ b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
@@ -6,6 +6,7 @@
use std::fmt::Display;
use std::marker::Unsize;
use std::ops::CoerceUnsized;
+use std::rc::Weak;
#[repr(transparent)]
struct X<'a, T: ?Sized> {
@@ -27,4 +28,11 @@ const Y: X<'static, i32> = X { f: &0 };
fn main() {
let _: [X<'static, dyn Display>; 0] = [Y; 0];
+ coercion_on_weak_in_const();
+}
+
+fn coercion_on_weak_in_const() {
+ const X: Weak = Weak::new();
+ const Y: [Weak; 0] = [X; 0];
+ let _ = Y;
}
--
cgit 1.4.1-3-g733a5
From b77de834c031890c048f8164d4b5979d2511c00e Mon Sep 17 00:00:00 2001
From: Ding Xiang Fei
Date: Thu, 25 Sep 2025 01:53:34 +0800
Subject: mark THIR use as candidate for constness check
---
compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs | 5 ++++-
tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs | 8 ++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
(limited to 'tests')
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index d6dc12e5955..3a5839f2d40 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -661,8 +661,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// operations that can be const-folded today.
fn check_constness(&self, mut kind: &'a ExprKind<'tcx>) -> bool {
loop {
+ debug!(?kind, "check_constness");
match kind {
- &ExprKind::PointerCoercion {
+ &ExprKind::ValueTypeAscription { source: eid, user_ty: _, user_ty_span: _ }
+ | &ExprKind::Use { source: eid }
+ | &ExprKind::PointerCoercion {
cast: PointerCoercion::Unsize,
source: eid,
is_from_as_cast: _,
diff --git a/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
index 5924809f34c..38479d9070b 100644
--- a/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
+++ b/tests/ui/coercion/no_local_for_coerced_const-issue-143671.rs
@@ -29,6 +29,7 @@ const Y: X<'static, i32> = X { f: &0 };
fn main() {
let _: [X<'static, dyn Display>; 0] = [Y; 0];
coercion_on_weak_in_const();
+ coercion_on_weak_as_cast();
}
fn coercion_on_weak_in_const() {
@@ -36,3 +37,10 @@ fn coercion_on_weak_in_const() {
const Y: [Weak; 0] = [X; 0];
let _ = Y;
}
+
+fn coercion_on_weak_as_cast() {
+ const Y: X<'static, i32> = X { f: &0 };
+ // What happens in the following code is that
+ // a constant is explicitly coerced into
+ let _a: [X<'static, dyn Display>; 0] = [Y as X<'static, dyn Display>; 0];
+}
--
cgit 1.4.1-3-g733a5
From bc37dd4a724fc3e3043a46f488775dbe1bfd9649 Mon Sep 17 00:00:00 2001
From: León Orell Valerian Liehr
Date: Wed, 24 Sep 2025 15:48:34 +0200
Subject: Remove an erroneous normalization step in
`tests/run-make/linker-warning`
---
tests/run-make/linker-warning/rmake.rs | 1 -
1 file changed, 1 deletion(-)
(limited to 'tests')
diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
index 9ea706af503..b0c40dd171d 100644
--- a/tests/run-make/linker-warning/rmake.rs
+++ b/tests/run-make/linker-warning/rmake.rs
@@ -61,7 +61,6 @@ fn main() {
diff()
.expected_file("short-error.txt")
.actual_text("(linker error)", out.stderr())
- .normalize(r#"/rustc[^/_-]*/"#, "/rustc/")
.normalize("libpanic_abort", "libpanic_unwind")
.normalize(
regex::escape(
--
cgit 1.4.1-3-g733a5