From f0fd6f78d48064972a5b7e73f219e0f99661b76e Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 18 Feb 2026 21:28:03 +0100 Subject: [PATCH 01/35] cleanup long shuffle mask literals --- .../src/arm_shared/neon/generated.rs | 240 +++--------------- .../spec/neon/arm_shared.spec.yml | 72 +++--- 2 files changed, 72 insertions(+), 240 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 45c83b880e907..13dee7a6e6e0e 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -10149,7 +10149,7 @@ pub fn vdotq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f16)"] @@ -10174,13 +10174,7 @@ pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdupq_lane_f16(a: float16x4_t) -> float16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f32)"] @@ -10341,7 +10335,7 @@ pub fn vdupq_lane_u32(a: uint32x2_t) -> uint32x4_t { )] pub fn vdup_lane_p16(a: poly16x4_t) -> poly16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s16)"] @@ -10364,7 +10358,7 @@ pub fn vdup_lane_p16(a: poly16x4_t) -> poly16x4_t { )] pub fn vdup_lane_s16(a: int16x4_t) -> int16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u16)"] @@ -10387,7 +10381,7 @@ pub fn vdup_lane_s16(a: int16x4_t) -> int16x4_t { )] pub fn vdup_lane_u16(a: uint16x4_t) -> uint16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p16)"] @@ -10410,13 +10404,7 @@ pub fn vdup_lane_u16(a: uint16x4_t) -> uint16x4_t { )] pub fn vdupq_lane_p16(a: poly16x4_t) -> poly16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s16)"] @@ -10439,13 +10427,7 @@ pub fn vdupq_lane_p16(a: poly16x4_t) -> poly16x8_t { )] pub fn vdupq_lane_s16(a: int16x4_t) -> int16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u16)"] @@ -10468,13 +10450,7 @@ pub fn vdupq_lane_s16(a: int16x4_t) -> int16x8_t { )] pub fn vdupq_lane_u16(a: uint16x4_t) -> uint16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p8)"] @@ -10497,13 +10473,7 @@ pub fn vdupq_lane_u16(a: uint16x4_t) -> uint16x8_t { )] pub fn vdup_lane_p8(a: poly8x8_t) -> poly8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s8)"] @@ -10526,13 +10496,7 @@ pub fn vdup_lane_p8(a: poly8x8_t) -> poly8x8_t { )] pub fn vdup_lane_s8(a: int8x8_t) -> int8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u8)"] @@ -10555,13 +10519,7 @@ pub fn vdup_lane_s8(a: int8x8_t) -> int8x8_t { )] pub fn vdup_lane_u8(a: uint8x8_t) -> uint8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p8)"] @@ -10584,16 +10542,7 @@ pub fn vdup_lane_u8(a: uint8x8_t) -> uint8x8_t { )] pub fn vdupq_lane_p8(a: poly8x8_t) -> poly8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s8)"] @@ -10616,16 +10565,7 @@ pub fn vdupq_lane_p8(a: poly8x8_t) -> poly8x16_t { )] pub fn vdupq_lane_s8(a: int8x8_t) -> int8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u8)"] @@ -10648,16 +10588,7 @@ pub fn vdupq_lane_s8(a: int8x8_t) -> int8x16_t { )] pub fn vdupq_lane_u8(a: uint8x8_t) -> uint8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s64)"] @@ -10728,7 +10659,7 @@ pub fn vdup_lane_u64(a: uint64x1_t) -> uint64x1_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f16)"] @@ -10753,13 +10684,7 @@ pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdupq_laneq_f16(a: float16x8_t) -> float16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f32)"] @@ -10920,7 +10845,7 @@ pub fn vdupq_laneq_u32(a: uint32x4_t) -> uint32x4_t { )] pub fn vdup_laneq_p16(a: poly16x8_t) -> poly16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s16)"] @@ -10943,7 +10868,7 @@ pub fn vdup_laneq_p16(a: poly16x8_t) -> poly16x4_t { )] pub fn vdup_laneq_s16(a: int16x8_t) -> int16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u16)"] @@ -10966,7 +10891,7 @@ pub fn vdup_laneq_s16(a: int16x8_t) -> int16x4_t { )] pub fn vdup_laneq_u16(a: uint16x8_t) -> uint16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p16)"] @@ -10989,13 +10914,7 @@ pub fn vdup_laneq_u16(a: uint16x8_t) -> uint16x4_t { )] pub fn vdupq_laneq_p16(a: poly16x8_t) -> poly16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s16)"] @@ -11018,13 +10937,7 @@ pub fn vdupq_laneq_p16(a: poly16x8_t) -> poly16x8_t { )] pub fn vdupq_laneq_s16(a: int16x8_t) -> int16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u16)"] @@ -11047,13 +10960,7 @@ pub fn vdupq_laneq_s16(a: int16x8_t) -> int16x8_t { )] pub fn vdupq_laneq_u16(a: uint16x8_t) -> uint16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p8)"] @@ -11076,13 +10983,7 @@ pub fn vdupq_laneq_u16(a: uint16x8_t) -> uint16x8_t { )] pub fn vdup_laneq_p8(a: poly8x16_t) -> poly8x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s8)"] @@ -11105,13 +11006,7 @@ pub fn vdup_laneq_p8(a: poly8x16_t) -> poly8x8_t { )] pub fn vdup_laneq_s8(a: int8x16_t) -> int8x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u8)"] @@ -11134,13 +11029,7 @@ pub fn vdup_laneq_s8(a: int8x16_t) -> int8x8_t { )] pub fn vdup_laneq_u8(a: uint8x16_t) -> uint8x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p8)"] @@ -11163,16 +11052,7 @@ pub fn vdup_laneq_u8(a: uint8x16_t) -> uint8x8_t { )] pub fn vdupq_laneq_p8(a: poly8x16_t) -> poly8x16_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s8)"] @@ -11195,16 +11075,7 @@ pub fn vdupq_laneq_p8(a: poly8x16_t) -> poly8x16_t { )] pub fn vdupq_laneq_s8(a: int8x16_t) -> int8x16_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u8)"] @@ -11227,16 +11098,7 @@ pub fn vdupq_laneq_s8(a: int8x16_t) -> int8x16_t { )] pub fn vdupq_laneq_u8(a: uint8x16_t) -> uint8x16_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s64)"] @@ -35894,7 +35756,7 @@ pub fn vqdmulhq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { pub fn vqdmull_lane_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(N, 2); unsafe { - let b: int16x4_t = simd_shuffle!(b, b, [N as u32, N as u32, N as u32, N as u32]); + let b: int16x4_t = simd_shuffle!(b, b, [N as u32; 4]); vqdmull_s16(a, b) } } @@ -35920,7 +35782,7 @@ pub fn vqdmull_lane_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t { pub fn vqdmull_lane_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(N, 1); unsafe { - let b: int32x2_t = simd_shuffle!(b, b, [N as u32, N as u32]); + let b: int32x2_t = simd_shuffle!(b, b, [N as u32; 2]); vqdmull_s32(a, b) } } @@ -37480,17 +37342,7 @@ pub fn vqrshrn_n_u16(a: uint16x8_t) -> uint8x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqrshiftnu.v8i8")] fn _vqrshrn_n_u16(a: uint16x8_t, n: uint16x8_t) -> uint8x8_t; } - unsafe { - _vqrshrn_n_u16( - a, - const { - uint16x8_t([ - -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, - -N as u16, - ]) - }, - ) - } + unsafe { _vqrshrn_n_u16(a, const { uint16x8_t([-N as u16; 8]) }) } } #[doc = "Unsigned signed saturating rounded shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u32)"] @@ -37506,12 +37358,7 @@ pub fn vqrshrn_n_u32(a: uint32x4_t) -> uint16x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqrshiftnu.v4i16")] fn _vqrshrn_n_u32(a: uint32x4_t, n: uint32x4_t) -> uint16x4_t; } - unsafe { - _vqrshrn_n_u32( - a, - const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }, - ) - } + unsafe { _vqrshrn_n_u32(a, const { uint32x4_t([-N as u32; 4]) }) } } #[doc = "Unsigned signed saturating rounded shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u64)"] @@ -37527,7 +37374,7 @@ pub fn vqrshrn_n_u64(a: uint64x2_t) -> uint32x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqrshiftnu.v2i32")] fn _vqrshrn_n_u64(a: uint64x2_t, n: uint64x2_t) -> uint32x2_t; } - unsafe { _vqrshrn_n_u64(a, const { uint64x2_t([-N as u64, -N as u64]) }) } + unsafe { _vqrshrn_n_u64(a, const { uint64x2_t([-N as u64; 2]) }) } } #[doc = "Unsigned signed saturating rounded shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u16)"] @@ -38922,17 +38769,7 @@ pub fn vqshrn_n_u16(a: uint16x8_t) -> uint8x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftnu.v8i8")] fn _vqshrn_n_u16(a: uint16x8_t, n: uint16x8_t) -> uint8x8_t; } - unsafe { - _vqshrn_n_u16( - a, - const { - uint16x8_t([ - -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, - -N as u16, - ]) - }, - ) - } + unsafe { _vqshrn_n_u16(a, const { uint16x8_t([-N as u16; 8]) }) } } #[doc = "Unsigned saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u32)"] @@ -38948,12 +38785,7 @@ pub fn vqshrn_n_u32(a: uint32x4_t) -> uint16x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftnu.v4i16")] fn _vqshrn_n_u32(a: uint32x4_t, n: uint32x4_t) -> uint16x4_t; } - unsafe { - _vqshrn_n_u32( - a, - const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }, - ) - } + unsafe { _vqshrn_n_u32(a, const { uint32x4_t([-N as u32; 4]) }) } } #[doc = "Unsigned saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u64)"] @@ -38969,7 +38801,7 @@ pub fn vqshrn_n_u64(a: uint64x2_t) -> uint32x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftnu.v2i32")] fn _vqshrn_n_u64(a: uint64x2_t, n: uint64x2_t) -> uint32x2_t; } - unsafe { _vqshrn_n_u64(a, const { uint64x2_t([-N as u64, -N as u64]) }) } + unsafe { _vqshrn_n_u64(a, const { uint64x2_t([-N as u64; 2]) }) } } #[doc = "Unsigned saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u16)"] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 8e10fff984ac7..90cd0c80a1c18 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -1439,12 +1439,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [_lane_s8, int8x8_t, int8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_s8, int8x8_t, int8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_u8, uint8x8_t, uint8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_u8, uint8x8_t, uint8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_p8, poly8x8_t, poly8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_p8, poly8x8_t, poly8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [_lane_s8, int8x8_t, int8x8_t, '3', '[N as u32; 8]'] + - [q_lane_s8, int8x8_t, int8x16_t, '3', '[N as u32; 16]'] + - [_lane_u8, uint8x8_t, uint8x8_t, '3', '[N as u32; 8]'] + - [q_lane_u8, uint8x8_t, uint8x16_t, '3', '[N as u32; 16]'] + - [_lane_p8, poly8x8_t, poly8x8_t, '3', '[N as u32; 8]'] + - [q_lane_p8, poly8x8_t, poly8x16_t, '3', '[N as u32; 16]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1463,12 +1463,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [q_laneq_s8, int8x16_t, int8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_s8, int8x16_t, int8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_u8, uint8x16_t, uint8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_u8, uint8x16_t, uint8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_p8, poly8x16_t, poly8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_p8, poly8x16_t, poly8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [q_laneq_s8, int8x16_t, int8x16_t, '4', '[N as u32; 16]'] + - [_laneq_s8, int8x16_t, int8x8_t, '4', '[N as u32; 8]'] + - [q_laneq_u8, uint8x16_t, uint8x16_t, '4', '[N as u32; 16]'] + - [_laneq_u8, uint8x16_t, uint8x8_t, '4', '[N as u32; 8]'] + - [q_laneq_p8, poly8x16_t, poly8x16_t, '4', '[N as u32; 16]'] + - [_laneq_p8, poly8x16_t, poly8x8_t, '4', '[N as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1487,12 +1487,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [_lane_s16, int16x4_t, int16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_s16, int16x4_t, int16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_u16, uint16x4_t, uint16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_u16, uint16x4_t, uint16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_p16, poly16x4_t, poly16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_p16, poly16x4_t, poly16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [_lane_s16, int16x4_t, int16x4_t, '2', '[N as u32; 4]'] + - [q_lane_s16, int16x4_t, int16x8_t, '2', '[N as u32; 8]'] + - [_lane_u16, uint16x4_t, uint16x4_t, '2', '[N as u32; 4]'] + - [q_lane_u16, uint16x4_t, uint16x8_t, '2', '[N as u32; 8]'] + - [_lane_p16, poly16x4_t, poly16x4_t, '2', '[N as u32; 4]'] + - [q_lane_p16, poly16x4_t, poly16x8_t, '2', '[N as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1511,12 +1511,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_s16, int16x8_t, int16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_u16, uint16x8_t, uint16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_u16, uint16x8_t, uint16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_p16, poly16x8_t, poly16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_p16, poly16x8_t, poly16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] + - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[N as u32; 8]'] + - [_laneq_s16, int16x8_t, int16x4_t, '3', '[N as u32; 4]'] + - [q_laneq_u16, uint16x8_t, uint16x8_t, '3', '[N as u32; 8]'] + - [_laneq_u16, uint16x8_t, uint16x4_t, '3', '[N as u32; 4]'] + - [q_laneq_p16, poly16x8_t, poly16x8_t, '3', '[N as u32; 8]'] + - [_laneq_p16, poly16x8_t, poly16x4_t, '3', '[N as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1538,8 +1538,8 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [q_laneq_f16, float16x8_t, float16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_f16, float16x8_t, float16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] + - [q_laneq_f16, float16x8_t, float16x8_t, '3', '[N as u32; 8]'] + - [_laneq_f16, float16x8_t, float16x4_t, '3', '[N as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1578,8 +1578,8 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [_lane_f16, float16x4_t, float16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_f16, float16x4_t, float16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [_lane_f16, float16x4_t, float16x4_t, '2', '[N as u32; 4]'] + - [q_lane_f16, float16x4_t, float16x8_t, '2', '[N as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -7675,7 +7675,7 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int16x4_t, int16x4_t, int32x4_t, '[N as u32, N as u32, N as u32, N as u32]'] + - [int16x4_t, int16x4_t, int32x4_t, '[N as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [N, '2']] - Let: [b, "{neon_type[0]}", {FnCall: [simd_shuffle!, [b, b, "{type[3]}"]]}] @@ -7695,7 +7695,7 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int32x2_t, int32x2_t, int64x2_t, '[N as u32, N as u32]'] + - [int32x2_t, int32x2_t, int64x2_t, '[N as u32; 2]'] compose: - FnCall: [static_assert_uimm_bits!, [N, '1']] - Let: [b, "{neon_type[0]}", {FnCall: [simd_shuffle!, [b, b, "{type[3]}"]]}] @@ -8320,9 +8320,9 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [uint16x8_t, uint8x8_t, 'N >= 1 && N <= 8', 'const { uint16x8_t([-N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16]) }'] - - [uint32x4_t, uint16x4_t, 'N >= 1 && N <= 16', 'const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }'] - - [uint64x2_t, uint32x2_t, 'N >= 1 && N <= 32', 'const { uint64x2_t([-N as u64, -N as u64]) }'] + - [uint16x8_t, uint8x8_t, 'N >= 1 && N <= 8', 'const { uint16x8_t([-N as u16; 8]) }'] + - [uint32x4_t, uint16x4_t, 'N >= 1 && N <= 16', 'const { uint32x4_t([-N as u32; 4]) }'] + - [uint64x2_t, uint32x2_t, 'N >= 1 && N <= 32', 'const { uint64x2_t([-N as u64; 2]) }'] compose: - FnCall: [static_assert!, ["{type[2]}"]] - LLVMLink: @@ -10789,9 +10789,9 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [uint16x8_t, uint8x8_t, '8', 'const { uint16x8_t([-N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16]) }'] - - [uint32x4_t, uint16x4_t, '16', 'const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }'] - - [uint64x2_t, uint32x2_t, '32', 'const { uint64x2_t([-N as u64, -N as u64]) }'] + - [uint16x8_t, uint8x8_t, '8', 'const { uint16x8_t([-N as u16; 8]) }'] + - [uint32x4_t, uint16x4_t, '16', 'const { uint32x4_t([-N as u32; 4]) }'] + - [uint64x2_t, uint32x2_t, '32', 'const { uint64x2_t([-N as u64; 2]) }'] compose: - FnCall: [static_assert!, ['N >= 1 && N <= {type[2]}']] - LLVMLink: From c0c9d025d5a0edcc34bf58645a74e76d4f6b5456 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 18 Feb 2026 21:23:00 +0100 Subject: [PATCH 02/35] use `intrinsics::simd` for interleaving store --- .../src/arm_shared/neon/generated.rs | 192 +++--------------- .../stdarch/crates/core_arch/src/macros.rs | 67 ++++++ .../spec/neon/arm_shared.spec.yml | 86 +++----- 3 files changed, 118 insertions(+), 227 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 45c83b880e907..37c7ef8fea887 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -66001,14 +66001,7 @@ pub unsafe fn vst2q_f16(a: *mut f16, b: float16x8x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_f32(a: *mut f32, b: float32x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2f32.p0" - )] - fn _vst2_f32(a: float32x2_t, b: float32x2_t, ptr: *mut i8); - } - _vst2_f32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(f32, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f32)"] @@ -66020,14 +66013,7 @@ pub unsafe fn vst2_f32(a: *mut f32, b: float32x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_f32(a: *mut f32, b: float32x4x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v4f32.p0" - )] - fn _vst2q_f32(a: float32x4_t, b: float32x4_t, ptr: *mut i8); - } - _vst2q_f32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(f32, 4, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s8)"] @@ -66039,14 +66025,7 @@ pub unsafe fn vst2q_f32(a: *mut f32, b: float32x4x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_s8(a: *mut i8, b: int8x8x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v8i8.p0" - )] - fn _vst2_s8(a: int8x8_t, b: int8x8_t, ptr: *mut i8); - } - _vst2_s8(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i8, 8, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s8)"] @@ -66058,14 +66037,7 @@ pub unsafe fn vst2_s8(a: *mut i8, b: int8x8x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s8(a: *mut i8, b: int8x16x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v16i8.p0" - )] - fn _vst2q_s8(a: int8x16_t, b: int8x16_t, ptr: *mut i8); - } - _vst2q_s8(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i8, 16, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s16)"] @@ -66077,14 +66049,7 @@ pub unsafe fn vst2q_s8(a: *mut i8, b: int8x16x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_s16(a: *mut i16, b: int16x4x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v4i16.p0" - )] - fn _vst2_s16(a: int16x4_t, b: int16x4_t, ptr: *mut i8); - } - _vst2_s16(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i16, 4, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s16)"] @@ -66096,14 +66061,7 @@ pub unsafe fn vst2_s16(a: *mut i16, b: int16x4x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s16(a: *mut i16, b: int16x8x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v8i16.p0" - )] - fn _vst2q_s16(a: int16x8_t, b: int16x8_t, ptr: *mut i8); - } - _vst2q_s16(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i16, 8, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s32)"] @@ -66115,14 +66073,7 @@ pub unsafe fn vst2q_s16(a: *mut i16, b: int16x8x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_s32(a: *mut i32, b: int32x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2i32.p0" - )] - fn _vst2_s32(a: int32x2_t, b: int32x2_t, ptr: *mut i8); - } - _vst2_s32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i32, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s32)"] @@ -66134,14 +66085,7 @@ pub unsafe fn vst2_s32(a: *mut i32, b: int32x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s32(a: *mut i32, b: int32x4x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v4i32.p0" - )] - fn _vst2q_s32(a: int32x4_t, b: int32x4_t, ptr: *mut i8); - } - _vst2q_s32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i32, 4, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f32)"] @@ -67233,11 +67177,7 @@ pub unsafe fn vst3q_f16(a: *mut f16, b: float16x8x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_f32(a: *mut f32, b: float32x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v2f32")] - fn _vst3_f32(ptr: *mut i8, a: float32x2_t, b: float32x2_t, c: float32x2_t, size: i32); - } - _vst3_f32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(f32, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f32)"] @@ -67249,11 +67189,7 @@ pub unsafe fn vst3_f32(a: *mut f32, b: float32x2x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_f32(a: *mut f32, b: float32x4x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v4f32")] - fn _vst3q_f32(ptr: *mut i8, a: float32x4_t, b: float32x4_t, c: float32x4_t, size: i32); - } - _vst3q_f32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(f32, 4, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s8)"] @@ -67265,11 +67201,7 @@ pub unsafe fn vst3q_f32(a: *mut f32, b: float32x4x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_s8(a: *mut i8, b: int8x8x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v8i8")] - fn _vst3_s8(ptr: *mut i8, a: int8x8_t, b: int8x8_t, c: int8x8_t, size: i32); - } - _vst3_s8(a as _, b.0, b.1, b.2, 1) + crate::core_arch::macros::interleaving_store!(i8, 8, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s8)"] @@ -67281,11 +67213,7 @@ pub unsafe fn vst3_s8(a: *mut i8, b: int8x8x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_s8(a: *mut i8, b: int8x16x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v16i8")] - fn _vst3q_s8(ptr: *mut i8, a: int8x16_t, b: int8x16_t, c: int8x16_t, size: i32); - } - _vst3q_s8(a as _, b.0, b.1, b.2, 1) + crate::core_arch::macros::interleaving_store!(i8, 16, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s16)"] @@ -67297,11 +67225,7 @@ pub unsafe fn vst3q_s8(a: *mut i8, b: int8x16x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_s16(a: *mut i16, b: int16x4x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v4i16")] - fn _vst3_s16(ptr: *mut i8, a: int16x4_t, b: int16x4_t, c: int16x4_t, size: i32); - } - _vst3_s16(a as _, b.0, b.1, b.2, 2) + crate::core_arch::macros::interleaving_store!(i16, 4, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s16)"] @@ -67313,11 +67237,7 @@ pub unsafe fn vst3_s16(a: *mut i16, b: int16x4x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_s16(a: *mut i16, b: int16x8x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v8i16")] - fn _vst3q_s16(ptr: *mut i8, a: int16x8_t, b: int16x8_t, c: int16x8_t, size: i32); - } - _vst3q_s16(a as _, b.0, b.1, b.2, 2) + crate::core_arch::macros::interleaving_store!(i16, 8, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s32)"] @@ -67329,11 +67249,7 @@ pub unsafe fn vst3q_s16(a: *mut i16, b: int16x8x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_s32(a: *mut i32, b: int32x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v2i32")] - fn _vst3_s32(ptr: *mut i8, a: int32x2_t, b: int32x2_t, c: int32x2_t, size: i32); - } - _vst3_s32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(i32, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s32)"] @@ -67345,11 +67261,7 @@ pub unsafe fn vst3_s32(a: *mut i32, b: int32x2x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_s32(a: *mut i32, b: int32x4x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v4i32")] - fn _vst3q_s32(ptr: *mut i8, a: int32x4_t, b: int32x4_t, c: int32x4_t, size: i32); - } - _vst3q_s32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(i32, 4, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f32)"] @@ -68712,14 +68624,7 @@ pub unsafe fn vst4q_s32(a: *mut i32, b: int32x4x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_f32(a: *mut f32, b: float32x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2f32.p0" - )] - fn _vst4_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t, d: float32x2_t, ptr: *mut i8); - } - _vst4_f32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(f32, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f32)"] @@ -68731,14 +68636,7 @@ pub unsafe fn vst4_f32(a: *mut f32, b: float32x2x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_f32(a: *mut f32, b: float32x4x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v4f32.p0" - )] - fn _vst4q_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t, d: float32x4_t, ptr: *mut i8); - } - _vst4q_f32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(f32, 4, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s8)"] @@ -68750,14 +68648,7 @@ pub unsafe fn vst4q_f32(a: *mut f32, b: float32x4x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_s8(a: *mut i8, b: int8x8x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v8i8.p0" - )] - fn _vst4_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t, d: int8x8_t, ptr: *mut i8); - } - _vst4_s8(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i8, 8, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s8)"] @@ -68769,14 +68660,7 @@ pub unsafe fn vst4_s8(a: *mut i8, b: int8x8x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s8(a: *mut i8, b: int8x16x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v16i8.p0" - )] - fn _vst4q_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: int8x16_t, ptr: *mut i8); - } - _vst4q_s8(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i8, 16, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s16)"] @@ -68788,14 +68672,7 @@ pub unsafe fn vst4q_s8(a: *mut i8, b: int8x16x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_s16(a: *mut i16, b: int16x4x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v4i16.p0" - )] - fn _vst4_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t, d: int16x4_t, ptr: *mut i8); - } - _vst4_s16(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i16, 4, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s16)"] @@ -68807,14 +68684,7 @@ pub unsafe fn vst4_s16(a: *mut i16, b: int16x4x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s16(a: *mut i16, b: int16x8x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v8i16.p0" - )] - fn _vst4q_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t, d: int16x8_t, ptr: *mut i8); - } - _vst4q_s16(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i16, 8, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s32)"] @@ -68826,14 +68696,7 @@ pub unsafe fn vst4q_s16(a: *mut i16, b: int16x8x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_s32(a: *mut i32, b: int32x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2i32.p0" - )] - fn _vst4_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t, d: int32x2_t, ptr: *mut i8); - } - _vst4_s32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i32, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s32)"] @@ -68845,14 +68708,7 @@ pub unsafe fn vst4_s32(a: *mut i32, b: int32x2x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s32(a: *mut i32, b: int32x4x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v4i32.p0" - )] - fn _vst4q_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t, d: int32x4_t, ptr: *mut i8); - } - _vst4q_s32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i32, 4, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f16)"] diff --git a/library/stdarch/crates/core_arch/src/macros.rs b/library/stdarch/crates/core_arch/src/macros.rs index 9f6922efeeb7d..5a582fe17772b 100644 --- a/library/stdarch/crates/core_arch/src/macros.rs +++ b/library/stdarch/crates/core_arch/src/macros.rs @@ -187,6 +187,17 @@ macro_rules! simd_masked_store { }; } +/// The first N indices `[0, 1, 2, ...]`. +pub(crate) const fn identity() -> [u32; N] { + let mut out = [0u32; N]; + let mut i = 0usize; + while i < N { + out[i] = i as u32; + i += 1; + } + out +} + /// The first N even indices `[0, 2, 4, ...]`. pub(crate) const fn even() -> [u32; N] { let mut out = [0u32; N]; @@ -277,3 +288,59 @@ macro_rules! deinterleaving_load { #[allow(unused)] pub(crate) use deinterleaving_load; + +pub(crate) const fn interleave_mask() +-> [u32; LANES] { + let mut out = [0u32; LANES]; + let mut j = 0usize; + while j < LANES { + out[j] = ((j % K) * N + j / K) as u32; + j += 1; + } + out +} + +#[allow(unused)] +macro_rules! interleaving_store { + ($elem:ty, $lanes:literal, 2, $ptr:expr, $v:expr) => {{ + use $crate::core_arch::macros::interleave_mask; + use $crate::core_arch::simd::Simd; + + type W = Simd<$elem, { $lanes * 2 }>; + let w: W = simd_shuffle!($v.0, $v.1, interleave_mask::<{ $lanes * 2 }, $lanes, 2>()); + $crate::ptr::write_unaligned($ptr as *mut W, w); + }}; + + // N = 3 + ($elem:ty, $lanes:literal, 3, $ptr:expr, $v:expr) => {{ + use $crate::core_arch::macros::{identity, interleave_mask}; + use $crate::core_arch::simd::Simd; + + let v0v1: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.0, $v.1, identity::<{ $lanes * 2 }>()); + let v2v2: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.2, $v.2, identity::<{ $lanes * 2 }>()); + + type W = Simd<$elem, { $lanes * 3 }>; + let w: W = simd_shuffle!(v0v1, v2v2, interleave_mask::<{ $lanes * 3 }, $lanes, 3>()); + $crate::ptr::write_unaligned($ptr as *mut W, w); + }}; + + // N = 4 + ($elem:ty, $lanes:literal, 4, $ptr:expr, $v:expr) => {{ + use $crate::core_arch::macros::{identity, interleave_mask}; + use $crate::core_arch::simd::Simd; + + let v0v1: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.0, $v.1, identity::<{ $lanes * 2 }>()); + let v2v3: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.2, $v.3, identity::<{ $lanes * 2 }>()); + + type W = Simd<$elem, { $lanes * 4 }>; + let w: W = simd_shuffle!(v0v1, v2v3, interleave_mask::<{ $lanes * 4 }, $lanes, 4>()); + $crate::ptr::write_unaligned($ptr as *mut W, w); + }}; +} + +#[allow(unused)] +pub(crate) use interleaving_store; diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 8e10fff984ac7..f890b39f071d2 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -5113,26 +5113,16 @@ intrinsics: safety: unsafe: [neon] types: - - [i8, int8x8x2_t, int8x8_t] - - [i16, int16x4x2_t, int16x4_t] - - [i32, int32x2x2_t, int32x2_t] - - [i8, int8x16x2_t, int8x16_t] - - [i16, int16x8x2_t, int16x8_t] - - [i32, int32x4x2_t, int32x4_t] - - [f32, float32x2x2_t, float32x2_t] - - [f32, float32x4x2_t, float32x4_t] + - [i8, int8x8x2_t, "8"] + - [i16, int16x4x2_t, "4"] + - [i32, int32x2x2_t, "2"] + - [i8, int8x16x2_t, "16"] + - [i16, int16x8x2_t, "8"] + - [i32, int32x4x2_t, "4"] + - [f32, float32x2x2_t, "2"] + - [f32, float32x4x2_t, "4"] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] - + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "2", a, b], [], true] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -5571,27 +5561,16 @@ intrinsics: safety: unsafe: [neon] types: - - [i8, int8x8x3_t, int8x8_t, '1'] - - [i16, int16x4x3_t, int16x4_t, '2'] - - [i32, int32x2x3_t, int32x2_t, '4'] - - [i8, int8x16x3_t, int8x16_t, '1'] - - [i16, int16x8x3_t, int16x8_t, '2'] - - [i32, int32x4x3_t, int32x4_t, '4'] - - [f32, float32x2x3_t, float32x2_t, '4'] - - [f32, float32x4x3_t, float32x4_t, '4'] + - [i8, int8x8x3_t, '8'] + - [i16, int16x4x3_t, '4'] + - [i32, int32x2x3_t, '2'] + - [i8, int8x16x3_t, '16'] + - [i16, int16x8x3_t, '8'] + - [i32, int32x4x3_t, '4'] + - [f32, float32x2x3_t, '2'] + - [f32, float32x4x3_t, '4'] compose: - - LLVMLink: - name: 'vst3.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst3.p0.v{neon_type[1].lane}{type[0]}' - arch: arm - - FnCall: ['_vst3{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', "{type[3]}"]] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "3", a, b], [], true] - name: "vst3{neon_type[1].nox}" @@ -6114,27 +6093,16 @@ intrinsics: safety: unsafe: [neon] types: - - [i8, int8x8x4_t, int8x8_t] - - [i16, int16x4x4_t, int16x4_t] - - [i32, int32x2x4_t, int32x2_t] - - [i8, int8x16x4_t, int8x16_t] - - [i16, int16x8x4_t, int16x8_t] - - [i32, int32x4x4_t, int32x4_t] - - [f32, float32x2x4_t, float32x2_t] - - [f32, float32x4x4_t, float32x4_t] + - [i8, int8x8x4_t, "8"] + - [i16, int16x4x4_t, "4"] + - [i32, int32x2x4_t, "2"] + - [i8, int8x16x4_t, "16"] + - [i16, int16x8x4_t, "8"] + - [i32, int32x4x4_t, "4"] + - [f32, float32x2x4_t, "2"] + - [f32, float32x4x4_t, "4"] compose: - - LLVMLink: - name: 'vst4.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "4", a, b], [], true] - name: "vst4{neon_type[1].nox}" From e219383c8f00a56d61e3101ac4feca383c4ecaca Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 18 Feb 2026 21:40:50 +0100 Subject: [PATCH 03/35] use `intrinsics::simd` for interleaving store of `int64x1` --- .../src/arm_shared/neon/generated.rs | 52 ++----------- .../spec/neon/arm_shared.spec.yml | 75 ++----------------- 2 files changed, 12 insertions(+), 115 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 37c7ef8fea887..62201edfdaf25 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -66809,11 +66809,7 @@ pub unsafe fn vst2_p64(a: *mut p64, b: poly64x1x2_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst2.v1i64.p0")] - fn _vst2_s64(ptr: *mut i8, a: int64x1_t, b: int64x1_t, size: i32); - } - _vst2_s64(a as _, b.0, b.1, 8) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s64)"] @@ -66825,14 +66821,7 @@ pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v1i64.p0" - )] - fn _vst2_s64(a: int64x1_t, b: int64x1_t, ptr: *mut i8); - } - _vst2_s64(b.0, b.1, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u64)"] @@ -68065,14 +68054,7 @@ pub unsafe fn vst3_p64(a: *mut p64, b: poly64x1x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v1i64.p0" - )] - fn _vst3_s64(a: int64x1_t, b: int64x1_t, c: int64x1_t, ptr: *mut i8); - } - _vst3_s64(b.0, b.1, b.2, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s64)"] @@ -68084,11 +68066,7 @@ pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v1i64")] - fn _vst3_s64(ptr: *mut i8, a: int64x1_t, b: int64x1_t, c: int64x1_t, size: i32); - } - _vst3_s64(a as _, b.0, b.1, b.2, 8) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u64)"] @@ -69432,18 +69410,7 @@ pub unsafe fn vst4_p64(a: *mut p64, b: poly64x1x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst4.p0.v1i64")] - fn _vst4_s64( - ptr: *mut i8, - a: int64x1_t, - b: int64x1_t, - c: int64x1_t, - d: int64x1_t, - size: i32, - ); - } - _vst4_s64(a as _, b.0, b.1, b.2, b.3, 8) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s64)"] @@ -69455,14 +69422,7 @@ pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v1i64.p0" - )] - fn _vst4_s64(a: int64x1_t, b: int64x1_t, c: int64x1_t, d: int64x1_t, ptr: *mut i8); - } - _vst4_s64(b.0, b.1, b.2, b.3, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u64)"] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index f890b39f071d2..23145d6d6692e 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -5049,17 +5049,7 @@ intrinsics: types: - [i64, int64x1x2_t, int64x1_t] compose: - - LLVMLink: - name: 'vst2.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst2.v{neon_type[1].lane}{type[0]}.p0' - arch: arm - - FnCall: ['_vst2{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', '8']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -5092,16 +5082,7 @@ intrinsics: types: - [i64, int64x1x2_t, int64x1_t] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -5416,17 +5397,7 @@ intrinsics: types: - [i64, int64x1x3_t, int64x1_t] compose: - - LLVMLink: - name: 'st3.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst3{neon_type[1].nox}" doc: "Store multiple 3-element structures from three registers" @@ -5461,18 +5432,7 @@ intrinsics: types: - [i64, int64x1x3_t, int64x1_t] compose: - - LLVMLink: - name: 'vst3.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst3.p0.v{neon_type[1].lane}{type[0]}' - arch: arm - - FnCall: ['_vst3{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', '8']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst3{neon_type[1].nox}" doc: "Store multiple 3-element structures from three registers" @@ -5832,19 +5792,7 @@ intrinsics: types: - [i64, int64x1x4_t, int64x1_t] compose: - - LLVMLink: - name: 'vst4.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst4.p0.v{neon_type[1].lane}{type[0]}' - arch: arm - - FnCall: ['_vst4{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', '8']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst4{neon_type[1].nox}" doc: "Store multiple 4-element structures from four registers" @@ -5858,18 +5806,7 @@ intrinsics: types: - [i64, int64x1x4_t, int64x1_t] compose: - - LLVMLink: - name: 'vst4.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.{neon_type[2]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst4{neon_type[1].nox}" doc: "Store multiple 4-element structures from four registers" From afb890e048205ba28b090c6607721dee2cb636bc Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 18 Feb 2026 21:51:54 +0100 Subject: [PATCH 04/35] use `intrinsics::simd` for interleaving store of f16 --- library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs index 2df4ba7443314..2fbd2255aa0fd 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs @@ -1050,6 +1050,14 @@ mod tests { test_vld1q_f16_x2(f16, 16, float16x8x2_t, vst1q_f16_x2, vld1q_f16_x2); test_vld1q_f16_x3(f16, 24, float16x8x3_t, vst1q_f16_x3, vld1q_f16_x3); test_vld1q_f16_x4(f16, 32, float16x8x4_t, vst1q_f16_x4, vld1q_f16_x4); + + test_vld2_f16_x2(f16, 8, float16x4x2_t, vst2_f16, vld2_f16); + test_vld2_f16_x3(f16, 12, float16x4x3_t, vst3_f16, vld3_f16); + test_vld2_f16_x4(f16, 16, float16x4x4_t, vst4_f16, vld4_f16); + + test_vld2q_f16_x2(f16, 16, float16x8x2_t, vst2q_f16, vld2q_f16); + test_vld3q_f16_x3(f16, 24, float16x8x3_t, vst3q_f16, vld3q_f16); + test_vld4q_f16_x4(f16, 32, float16x8x4_t, vst4q_f16, vld4q_f16); } macro_rules! wide_store_load_roundtrip_aes { From 2b656f99a5cd12722831a1a92365a8000b61602a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 18 Feb 2026 22:27:23 +0100 Subject: [PATCH 05/35] use `intrinsics::simd` for aarch64 interleaving `st` --- .../core_arch/src/aarch64/neon/generated.rs | 83 ++--------------- .../spec/neon/aarch64.spec.yml | 92 ++++--------------- 2 files changed, 26 insertions(+), 149 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 88afaae8b80d3..41f01d445fc71 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -25039,16 +25039,9 @@ pub unsafe fn vst1q_lane_f64(a: *mut f64, b: float64x2_t) { #[inline(always)] #[target_feature(enable = "neon")] #[stable(feature = "neon_intrinsics", since = "1.59.0")] -#[cfg_attr(test, assert_instr(st1))] +#[cfg_attr(test, assert_instr(stp))] pub unsafe fn vst2_f64(a: *mut f64, b: float64x1x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v1f64.p0" - )] - fn _vst2_f64(a: float64x1_t, b: float64x1_t, ptr: *mut i8); - } - _vst2_f64(b.0, b.1, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f64)"] @@ -25125,14 +25118,7 @@ pub unsafe fn vst2_lane_u64(a: *mut u64, b: uint64x1x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_f64(a: *mut f64, b: float64x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2f64.p0" - )] - fn _vst2q_f64(a: float64x2_t, b: float64x2_t, ptr: *mut i8); - } - _vst2q_f64(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(f64, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s64)"] @@ -25143,14 +25129,7 @@ pub unsafe fn vst2q_f64(a: *mut f64, b: float64x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s64(a: *mut i64, b: int64x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2i64.p0" - )] - fn _vst2q_s64(a: int64x2_t, b: int64x2_t, ptr: *mut i8); - } - _vst2q_s64(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i64, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f64)"] @@ -25295,14 +25274,7 @@ pub unsafe fn vst2q_u64(a: *mut u64, b: uint64x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst3_f64(a: *mut f64, b: float64x1x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v1f64.p0" - )] - fn _vst3_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t, ptr: *mut i8); - } - _vst3_f64(b.0, b.1, b.2, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f64)"] @@ -25379,14 +25351,7 @@ pub unsafe fn vst3_lane_u64(a: *mut u64, b: uint64x1x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st3))] pub unsafe fn vst3q_f64(a: *mut f64, b: float64x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v2f64.p0" - )] - fn _vst3q_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t, ptr: *mut i8); - } - _vst3q_f64(b.0, b.1, b.2, a as _) + crate::core_arch::macros::interleaving_store!(f64, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s64)"] @@ -25397,14 +25362,7 @@ pub unsafe fn vst3q_f64(a: *mut f64, b: float64x2x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st3))] pub unsafe fn vst3q_s64(a: *mut i64, b: int64x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v2i64.p0" - )] - fn _vst3q_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t, ptr: *mut i8); - } - _vst3q_s64(b.0, b.1, b.2, a as _) + crate::core_arch::macros::interleaving_store!(i64, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f64)"] @@ -25549,14 +25507,7 @@ pub unsafe fn vst3q_u64(a: *mut u64, b: uint64x2x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst4_f64(a: *mut f64, b: float64x1x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v1f64.p0" - )] - fn _vst4_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t, d: float64x1_t, ptr: *mut i8); - } - _vst4_f64(b.0, b.1, b.2, b.3, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f64)"] @@ -25647,14 +25598,7 @@ pub unsafe fn vst4_lane_u64(a: *mut u64, b: uint64x1x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_f64(a: *mut f64, b: float64x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2f64.p0" - )] - fn _vst4q_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t, d: float64x2_t, ptr: *mut i8); - } - _vst4q_f64(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(f64, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s64)"] @@ -25665,14 +25609,7 @@ pub unsafe fn vst4q_f64(a: *mut f64, b: float64x2x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s64(a: *mut i64, b: int64x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2i64.p0" - )] - fn _vst4q_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t, d: int64x2_t, ptr: *mut i8); - } - _vst4q_s64(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i64, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f64)"] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index 9190c8518a667..0ec8024fdfbb6 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -4567,20 +4567,11 @@ intrinsics: unsafe: [neon] attr: - *neon-stable - assert_instr: [st1] + assert_instr: [stp] types: - - ['f64', float64x1x2_t, float64x1_t] + - ['f64', float64x1x2_t] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -4591,19 +4582,10 @@ intrinsics: - *neon-stable assert_instr: [st2] types: - - [i64, int64x2x2_t, int64x2_t] - - [f64, float64x2x2_t, float64x2_t] + - [i64, int64x2x2_t, "2"] + - [f64, float64x2x2_t, "2"] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "2", a, b], [], true] - name: "vst2{neon_type[1].lane_nox}" doc: "Store multiple 2-element structures from two registers" @@ -4781,19 +4763,9 @@ intrinsics: safety: unsafe: [neon] types: - - [f64, float64x1x3_t, float64x1_t] + - [f64, float64x1x3_t] compose: - - LLVMLink: - name: 'st3.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst3{neon_type[1].lane_nox}" doc: "Store multiple 3-element structures from three registers" @@ -4860,20 +4832,10 @@ intrinsics: safety: unsafe: [neon] types: - - [i64, int64x2x3_t, int64x2_t] - - [f64, float64x2x3_t, float64x2_t] + - [i64, int64x2x3_t, "2"] + - [f64, float64x2x3_t, "2"] compose: - - LLVMLink: - name: 'st3.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "3", a, b], [], true] - name: "vst3{neon_type[1].nox}" doc: "Store multiple 3-element structures from three registers" @@ -4995,20 +4957,9 @@ intrinsics: safety: unsafe: [neon] types: - - [f64, float64x1x4_t, float64x1_t] + - [f64, float64x1x4_t] compose: - - LLVMLink: - name: 'st4.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst4{neon_type[1].lane_nox}" doc: "Store multiple 4-element structures from four registers" @@ -5075,21 +5026,10 @@ intrinsics: safety: unsafe: [neon] types: - - [i64, int64x2x4_t, int64x2_t] - - [f64, float64x2x4_t, float64x2_t] + - [i64, int64x2x4_t, "2"] + - [f64, float64x2x4_t, "2"] compose: - - LLVMLink: - name: 'st4.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "4", a, b], [], true] - name: "vst4{neon_type[1].nox}" doc: "Store multiple 4-element structures from four registers" From a5ba7941f93f3a619247e583e0a913e2c3a7613d Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Thu, 19 Feb 2026 06:50:17 -0500 Subject: [PATCH 06/35] x86: use `simd::intrinsics` for saturating packs Use intrinsics for `sse2`, `sse41`, `avx2`, `avx512bw` The majority of implementations make use of `simd_shuffle` since that optimized through to the avx512 intrinsics that made use of the lower target feature intrinsics. Combined with masked stores, instruction tests would fail presumably due to the casting and clamping that the compiler couldn't see through. This is a known weakness as seen in the other masked stores like the truncating conversion stores. --- .../stdarch/crates/core_arch/src/x86/sse2.rs | 67 +++++++++++++++---- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index f339a003df4d1..fbf62c362f51b 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -1484,7 +1484,7 @@ pub const fn _mm_move_epi64(a: __m128i) -> __m128i { } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using signed saturation. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi16) @@ -1493,10 +1493,27 @@ pub const fn _mm_move_epi64(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(packsswb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packsswb(a.as_i16x8(), b.as_i16x8())) } + unsafe { + let max = simd_splat(i16::from(i8::MAX)); + let min = simd_splat(i16::from(i8::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + let clamped_b = simd_imax(simd_imin(b.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + + // Shuffle the low i8 of each i16 from two concatenated vectors into + // the low bits of the result register. + const IDXS: [u32; 16] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]; + let result: i8x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m128i() + } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using signed saturation. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi32) @@ -1505,10 +1522,23 @@ pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(packssdw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packssdw(a.as_i32x4(), b.as_i32x4())) } + unsafe { + let max = simd_splat(i32::from(i16::MAX)); + let min = simd_splat(i32::from(i16::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i32x4(), max), min); + let clamped_b = simd_imax(simd_imin(b.as_i32x4(), max), min); + + let clamped_a: i16x4 = simd_cast(clamped_a); + let clamped_b: i16x4 = simd_cast(clamped_b); + + let a: i64 = transmute(clamped_a); + let b: i64 = transmute(clamped_b); + i64x2::new(a, b).as_m128i() + } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using unsigned saturation. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi16) @@ -1517,7 +1547,26 @@ pub fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(packuswb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packuswb(a.as_i16x8(), b.as_i16x8())) } + unsafe { + let max = simd_splat(i16::from(u8::MAX)); + let min = simd_splat(i16::from(u8::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + let clamped_b = simd_imax(simd_imin(b.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + + // Shuffle the low bytes of each i16 from two concatenated vectors into + // the low bits of the result register. + // Without `simd_shuffle`, this intrinsic will cause the AVX-512BW + // `_mm_mask_packus_epi16` and `_mm_maskz_packus_epi16` tests to fail. + const IDXS: [u32; 16] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]; + let result: i8x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m128i() + } } /// Returns the `imm8` element of `a`. @@ -3217,12 +3266,6 @@ unsafe extern "C" { fn cvtps2dq(a: __m128) -> i32x4; #[link_name = "llvm.x86.sse2.maskmov.dqu"] fn maskmovdqu(a: i8x16, mask: i8x16, mem_addr: *mut i8); - #[link_name = "llvm.x86.sse2.packsswb.128"] - fn packsswb(a: i16x8, b: i16x8) -> i8x16; - #[link_name = "llvm.x86.sse2.packssdw.128"] - fn packssdw(a: i32x4, b: i32x4) -> i16x8; - #[link_name = "llvm.x86.sse2.packuswb.128"] - fn packuswb(a: i16x8, b: i16x8) -> u8x16; #[link_name = "llvm.x86.sse2.max.sd"] fn maxsd(a: __m128d, b: __m128d) -> __m128d; #[link_name = "llvm.x86.sse2.max.pd"] From 6fa33bea62865ebbfb58b88f689e4210b0769c1f Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Thu, 19 Feb 2026 07:05:07 -0500 Subject: [PATCH 07/35] Use intrinsics for `sse41` --- .../stdarch/crates/core_arch/src/x86/sse41.rs | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse41.rs b/library/stdarch/crates/core_arch/src/x86/sse41.rs index 7ad4306f36f21..8036f24e24d37 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse41.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse41.rs @@ -418,7 +418,7 @@ pub const fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_u32x4(), b.as_u32x4()).as_m128i() } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using unsigned saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi32) @@ -427,7 +427,24 @@ pub const fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(packusdw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_packus_epi32(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packusdw(a.as_i32x4(), b.as_i32x4())) } + unsafe { + let max = simd_splat(i32::from(u16::MAX)); + let min = simd_splat(i32::from(u16::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i32x4(), max), min) + .as_m128i() + .as_i16x8(); + let clamped_b = simd_imax(simd_imin(b.as_i32x4(), max), min) + .as_m128i() + .as_i16x8(); + + // Shuffle the low u16 of each i32 from two concatenated vectors into + // the low bits of the result register. + const IDXS: [u32; 8] = [0, 2, 4, 6, 8, 10, 12, 14]; + let result: i16x8 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m128i() + } } /// Compares packed 64-bit integers in `a` and `b` for equality @@ -1166,8 +1183,6 @@ pub unsafe fn _mm_stream_load_si128(mem_addr: *const __m128i) -> __m128i { unsafe extern "C" { #[link_name = "llvm.x86.sse41.insertps"] fn insertps(a: __m128, b: __m128, imm8: u8) -> __m128; - #[link_name = "llvm.x86.sse41.packusdw"] - fn packusdw(a: i32x4, b: i32x4) -> u16x8; #[link_name = "llvm.x86.sse41.dppd"] fn dppd(a: __m128d, b: __m128d, imm8: u8) -> __m128d; #[link_name = "llvm.x86.sse41.dpps"] From 639b07ec7513d655fd674ce109ec3b3e165ff441 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Thu, 19 Feb 2026 08:06:24 -0500 Subject: [PATCH 08/35] Use intrinsics for `avx2` --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 108 +++++++++++++++--- 1 file changed, 92 insertions(+), 16 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 04a88e461f752..ca4ca9a2de9a4 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -2315,7 +2315,7 @@ pub const fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_or(a.as_i32x8(), b.as_i32x8())) } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using signed saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packs_epi16) @@ -2324,10 +2324,31 @@ pub const fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpacksswb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packsswb(a.as_i16x16(), b.as_i16x16())) } + unsafe { + let max = simd_splat(i16::from(i8::MAX)); + let min = simd_splat(i16::from(i8::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + let clamped_b = simd_imax(simd_imin(b.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, 08, 10, 12, 14, // a-lo i16 to i8 conversions + 32, 34, 36, 38, 40, 42, 44, 46, // b-lo + 16, 18, 20, 22, 24, 26, 28, 30, // a-hi + 48, 50, 52, 54, 56, 58, 60, 62, // b-hi + ]; + let result: i8x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using signed saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packs_epi32) @@ -2336,10 +2357,31 @@ pub fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpackssdw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packssdw(a.as_i32x8(), b.as_i32x8())) } + unsafe { + let max = simd_splat(i32::from(i16::MAX)); + let min = simd_splat(i32::from(i16::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + let clamped_b = simd_imax(simd_imin(b.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + + #[rustfmt::skip] + const IDXS: [u32; 16] = [ + 00, 02, 04, 06, // a-lo i32 to i16 conversions + 16, 18, 20, 22, // b-lo + 08, 10, 12, 14, // a-hi + 24, 26, 28, 30, // b-hi + ]; + let result: i16x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using unsigned saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packus_epi16) @@ -2348,10 +2390,31 @@ pub fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpackuswb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packuswb(a.as_i16x16(), b.as_i16x16())) } + unsafe { + let max = simd_splat(i16::from(u8::MAX)); + let min = simd_splat(i16::from(u8::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + let clamped_b = simd_imax(simd_imin(b.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, 08, 10, 12, 14, // a-lo i16 to u8 conversions + 32, 34, 36, 38, 40, 42, 44, 46, // b-lo + 16, 18, 20, 22, 24, 26, 28, 30, // a-hi + 48, 50, 52, 54, 56, 58, 60, 62, // b-hi + ]; + let result: i8x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using unsigned saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packus_epi32) @@ -2360,7 +2423,28 @@ pub fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpackusdw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_packus_epi32(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packusdw(a.as_i32x8(), b.as_i32x8())) } + unsafe { + let max = simd_splat(i32::from(u16::MAX)); + let min = simd_splat(i32::from(u16::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + let clamped_b = simd_imax(simd_imin(b.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + + #[rustfmt::skip] + const IDXS: [u32; 16] = [ + 00, 02, 04, 06, // a-lo i32 to u16 conversions + 16, 18, 20, 22, // b-lo + 08, 10, 12, 14, // a-hi + 24, 26, 28, 30, // b-hi + ]; + let result: i16x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } /// Permutes packed 32-bit integers from `a` according to the content of `b`. @@ -3827,14 +3911,6 @@ unsafe extern "C" { fn mpsadbw(a: u8x32, b: u8x32, imm8: i8) -> u16x16; #[link_name = "llvm.x86.avx2.pmul.hr.sw"] fn pmulhrsw(a: i16x16, b: i16x16) -> i16x16; - #[link_name = "llvm.x86.avx2.packsswb"] - fn packsswb(a: i16x16, b: i16x16) -> i8x32; - #[link_name = "llvm.x86.avx2.packssdw"] - fn packssdw(a: i32x8, b: i32x8) -> i16x16; - #[link_name = "llvm.x86.avx2.packuswb"] - fn packuswb(a: i16x16, b: i16x16) -> u8x32; - #[link_name = "llvm.x86.avx2.packusdw"] - fn packusdw(a: i32x8, b: i32x8) -> u16x16; #[link_name = "llvm.x86.avx2.psad.bw"] fn psadbw(a: u8x32, b: u8x32) -> u64x4; #[link_name = "llvm.x86.avx2.psign.b"] From c7ecbd5e4b412a3ee76463037ac46ab401a62c5b Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Thu, 19 Feb 2026 08:42:08 -0500 Subject: [PATCH 09/35] Use intrinsics for `avx512bw` --- .../crates/core_arch/src/x86/avx512bw.rs | 117 ++++++++++++++++-- 1 file changed, 104 insertions(+), 13 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 3ba171c0fa50f..78801e8902107 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6524,7 +6524,32 @@ pub fn _mm_maskz_maddubs_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] pub fn _mm512_packs_epi32(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpackssdw(a.as_i32x16(), b.as_i32x16())) } + unsafe { + let max = simd_splat(i32::from(i16::MAX)); + let min = simd_splat(i32::from(i16::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + let clamped_b = simd_imax(simd_imin(b.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, + 32, 34, 36, 38, + 08, 10, 12, 14, + 40, 42, 44, 46, + 16, 18, 20, 22, + 48, 50, 52, 54, + 24, 26, 28, 30, + 56, 58, 60, 62, + ]; + let result: i16x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 32-bit integers from a and b to packed 16-bit integers using signed saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6619,7 +6644,32 @@ pub fn _mm_maskz_packs_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] pub fn _mm512_packs_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpacksswb(a.as_i16x32(), b.as_i16x32())) } + unsafe { + let max = simd_splat(i16::from(i8::MAX)); + let min = simd_splat(i16::from(i8::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + let clamped_b = simd_imax(simd_imin(b.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + + #[rustfmt::skip] + const IDXS: [u32; 64] = [ + 000, 002, 004, 006, 008, 010, 012, 014, + 064, 066, 068, 070, 072, 074, 076, 078, + 016, 018, 020, 022, 024, 026, 028, 030, + 080, 082, 084, 086, 088, 090, 092, 094, + 032, 034, 036, 038, 040, 042, 044, 046, + 096, 098, 100, 102, 104, 106, 108, 110, + 048, 050, 052, 054, 056, 058, 060, 062, + 112, 114, 116, 118, 120, 122, 124, 126, + ]; + let result: i8x64 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 16-bit integers from a and b to packed 8-bit integers using signed saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6714,7 +6764,32 @@ pub fn _mm_maskz_packs_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] pub fn _mm512_packus_epi32(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpackusdw(a.as_i32x16(), b.as_i32x16())) } + unsafe { + let max = simd_splat(i32::from(u16::MAX)); + let min = simd_splat(i32::from(u16::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + let clamped_b = simd_imax(simd_imin(b.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, + 32, 34, 36, 38, + 08, 10, 12, 14, + 40, 42, 44, 46, + 16, 18, 20, 22, + 48, 50, 52, 54, + 24, 26, 28, 30, + 56, 58, 60, 62, + ]; + let result: i16x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 32-bit integers from a and b to packed 16-bit integers using unsigned saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6809,7 +6884,32 @@ pub fn _mm_maskz_packus_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] pub fn _mm512_packus_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpackuswb(a.as_i16x32(), b.as_i16x32())) } + unsafe { + let max = simd_splat(i16::from(u8::MAX)); + let min = simd_splat(i16::from(u8::MIN)); + + let clamped_a = simd_imax(simd_imin(a.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + let clamped_b = simd_imax(simd_imin(b.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + + #[rustfmt::skip] + const IDXS: [u32; 64] = [ + 000, 002, 004, 006, 008, 010, 012, 014, + 064, 066, 068, 070, 072, 074, 076, 078, + 016, 018, 020, 022, 024, 026, 028, 030, + 080, 082, 084, 086, 088, 090, 092, 094, + 032, 034, 036, 038, 040, 042, 044, 046, + 096, 098, 100, 102, 104, 106, 108, 110, + 048, 050, 052, 054, 056, 058, 060, 062, + 112, 114, 116, 118, 120, 122, 124, 126, + ]; + let result: i8x64 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 16-bit integers from a and b to packed 8-bit integers using unsigned saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -12606,15 +12706,6 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.pmaddubs.w.512"] fn vpmaddubsw(a: u8x64, b: i8x64) -> i16x32; - #[link_name = "llvm.x86.avx512.packssdw.512"] - fn vpackssdw(a: i32x16, b: i32x16) -> i16x32; - #[link_name = "llvm.x86.avx512.packsswb.512"] - fn vpacksswb(a: i16x32, b: i16x32) -> i8x64; - #[link_name = "llvm.x86.avx512.packusdw.512"] - fn vpackusdw(a: i32x16, b: i32x16) -> u16x32; - #[link_name = "llvm.x86.avx512.packuswb.512"] - fn vpackuswb(a: i16x32, b: i16x32) -> u8x64; - #[link_name = "llvm.x86.avx512.psll.w.512"] fn vpsllw(a: i16x32, count: i16x8) -> i16x32; From 22d10c516d0b2cb1dd90a489bfd5402a96106f3e Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 20 Feb 2026 06:53:07 -0500 Subject: [PATCH 10/35] x86: Followup to add const for pack intrinsics Add const to `sse2`, `sse41`, `avx2`, and `avx512bw` functions and tests --- .../crates/core_arch/src/x86/avx512bw.rs | 30 +++++++++++-------- .../stdarch/crates/core_arch/src/x86/sse2.rs | 27 +++++++++-------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 78801e8902107..8481edcdb38d6 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6615,7 +6615,8 @@ pub fn _mm256_maskz_packs_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm_mask_packs_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packs_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, src.as_i16x8())) @@ -6629,7 +6630,8 @@ pub fn _mm_mask_packs_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) - #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm_maskz_packs_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packs_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, i16x8::ZERO)) @@ -6735,7 +6737,8 @@ pub fn _mm256_maskz_packs_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm_mask_packs_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packs_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, src.as_i8x16())) @@ -6749,7 +6752,8 @@ pub fn _mm_mask_packs_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm_maskz_packs_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packs_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, i8x16::ZERO)) @@ -6975,7 +6979,8 @@ pub fn _mm256_maskz_packus_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm_mask_packus_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packus_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, src.as_i8x16())) @@ -6989,7 +6994,8 @@ pub fn _mm_mask_packus_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm_maskz_packus_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packus_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, i8x16::ZERO)) @@ -17854,7 +17860,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packs_epi32() { + const fn test_mm_mask_packs_epi32() { let a = _mm_set1_epi32(i32::MAX); let b = _mm_set1_epi32(1 << 16 | 1); let r = _mm_mask_packs_epi32(a, 0, a, b); @@ -17865,7 +17871,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packs_epi32() { + const fn test_mm_maskz_packs_epi32() { let a = _mm_set1_epi32(i32::MAX); let b = _mm_set1_epi32(1); let r = _mm_maskz_packs_epi32(0, a, b); @@ -17954,7 +17960,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packs_epi16() { + const fn test_mm_mask_packs_epi16() { let a = _mm_set1_epi16(i16::MAX); let b = _mm_set1_epi16(1 << 8 | 1); let r = _mm_mask_packs_epi16(a, 0, a, b); @@ -17966,7 +17972,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packs_epi16() { + const fn test_mm_maskz_packs_epi16() { let a = _mm_set1_epi16(i16::MAX); let b = _mm_set1_epi16(1); let r = _mm_maskz_packs_epi16(0, a, b); @@ -18137,7 +18143,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packus_epi16() { + const fn test_mm_mask_packus_epi16() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(1 << 8 | 1); let r = _mm_mask_packus_epi16(a, 0, a, b); @@ -18148,7 +18154,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packus_epi16() { + const fn test_mm_maskz_packus_epi16() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(1); let r = _mm_maskz_packus_epi16(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index fbf62c362f51b..1f97f3c69d0e3 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -1492,10 +1492,11 @@ pub const fn _mm_move_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(packsswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { - let max = simd_splat(i16::from(i8::MAX)); - let min = simd_splat(i16::from(i8::MIN)); + let max = simd_splat(i8::MAX as i16); + let min = simd_splat(i8::MIN as i16); let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min) .as_m128i() @@ -1521,10 +1522,11 @@ pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(packssdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { - let max = simd_splat(i32::from(i16::MAX)); - let min = simd_splat(i32::from(i16::MIN)); + let max = simd_splat(i16::MAX as i32); + let min = simd_splat(i16::MIN as i32); let clamped_a = simd_imax(simd_imin(a.as_i32x4(), max), min); let clamped_b = simd_imax(simd_imin(b.as_i32x4(), max), min); @@ -1546,10 +1548,11 @@ pub fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(packuswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { - let max = simd_splat(i16::from(u8::MAX)); - let min = simd_splat(i16::from(u8::MIN)); + let max = simd_splat(u8::MAX as i16); + let min = simd_splat(u8::MIN as i16); let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min) .as_m128i() @@ -4329,7 +4332,7 @@ mod tests { } #[simd_test(enable = "sse2")] - fn test_mm_packs_epi16() { + const fn test_mm_packs_epi16() { let a = _mm_setr_epi16(0x80, -0x81, 0, 0, 0, 0, 0, 0); let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -0x81, 0x80); let r = _mm_packs_epi16(a, b); @@ -4343,7 +4346,7 @@ mod tests { } #[simd_test(enable = "sse2")] - fn test_mm_packs_epi32() { + const fn test_mm_packs_epi32() { let a = _mm_setr_epi32(0x8000, -0x8001, 0, 0); let b = _mm_setr_epi32(0, 0, -0x8001, 0x8000); let r = _mm_packs_epi32(a, b); @@ -4354,7 +4357,7 @@ mod tests { } #[simd_test(enable = "sse2")] - fn test_mm_packus_epi16() { + const fn test_mm_packus_epi16() { let a = _mm_setr_epi16(0x100, -1, 0, 0, 0, 0, 0, 0); let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -1, 0x100); let r = _mm_packus_epi16(a, b); From 17a4c8ea8fa5c17fb698e6a3f3194ef1ac79c7d5 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 20 Feb 2026 07:02:29 -0500 Subject: [PATCH 11/35] Add const to `sse41` intrinsics --- library/stdarch/crates/core_arch/src/x86/avx512bw.rs | 10 ++++++---- library/stdarch/crates/core_arch/src/x86/sse41.rs | 9 +++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 8481edcdb38d6..360b755d5818a 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6859,7 +6859,8 @@ pub fn _mm256_maskz_packus_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm_mask_packus_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packus_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, src.as_i16x8())) @@ -6873,7 +6874,8 @@ pub fn _mm_mask_packus_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm_maskz_packus_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packus_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, i16x8::ZERO)) @@ -18043,7 +18045,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packus_epi32() { + const fn test_mm_mask_packus_epi32() { let a = _mm_set1_epi32(-1); let b = _mm_set1_epi32(1 << 16 | 1); let r = _mm_mask_packus_epi32(a, 0, a, b); @@ -18054,7 +18056,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packus_epi32() { + const fn test_mm_maskz_packus_epi32() { let a = _mm_set1_epi32(-1); let b = _mm_set1_epi32(1); let r = _mm_maskz_packus_epi32(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/sse41.rs b/library/stdarch/crates/core_arch/src/x86/sse41.rs index 8036f24e24d37..4ebf7d3bd39a8 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse41.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse41.rs @@ -426,10 +426,11 @@ pub const fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(packusdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packus_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packus_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { - let max = simd_splat(i32::from(u16::MAX)); - let min = simd_splat(i32::from(u16::MIN)); + let max = simd_splat(u16::MAX as i32); + let min = simd_splat(u16::MIN as i32); let clamped_a = simd_imax(simd_imin(a.as_i32x4(), max), min) .as_m128i() @@ -1470,7 +1471,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - fn test_mm_packus_epi32() { + const fn test_mm_packus_epi32() { let a = _mm_setr_epi32(1, 2, 3, 4); let b = _mm_setr_epi32(-1, -2, -3, -4); let r = _mm_packus_epi32(a, b); From 4f881c4b89bc86577eeb63767292bac5d5896270 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 20 Feb 2026 07:10:51 -0500 Subject: [PATCH 12/35] Add const to `avx2` intrinsics --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 36 ++++++------ .../crates/core_arch/src/x86/avx512bw.rs | 55 ++++++++++++++----- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index ca4ca9a2de9a4..b49ad9522a412 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -2323,10 +2323,11 @@ pub const fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpacksswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { - let max = simd_splat(i16::from(i8::MAX)); - let min = simd_splat(i16::from(i8::MIN)); + let max = simd_splat(i8::MAX as i16); + let min = simd_splat(i8::MIN as i16); let clamped_a = simd_imax(simd_imin(a.as_i16x16(), max), min) .as_m256i() @@ -2356,10 +2357,11 @@ pub fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpackssdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { - let max = simd_splat(i32::from(i16::MAX)); - let min = simd_splat(i32::from(i16::MIN)); + let max = simd_splat(i16::MAX as i32); + let min = simd_splat(i16::MIN as i32); let clamped_a = simd_imax(simd_imin(a.as_i32x8(), max), min) .as_m256i() @@ -2389,10 +2391,11 @@ pub fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpackuswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { - let max = simd_splat(i16::from(u8::MAX)); - let min = simd_splat(i16::from(u8::MIN)); + let max = simd_splat(u8::MAX as i16); + let min = simd_splat(u8::MIN as i16); let clamped_a = simd_imax(simd_imin(a.as_i16x16(), max), min) .as_m256i() @@ -2422,10 +2425,11 @@ pub fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpackusdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packus_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packus_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { - let max = simd_splat(i32::from(u16::MAX)); - let min = simd_splat(i32::from(u16::MIN)); + let max = simd_splat(u16::MAX as i32); + let min = simd_splat(u16::MIN as i32); let clamped_a = simd_imax(simd_imin(a.as_i32x8(), max), min) .as_m256i() @@ -5064,7 +5068,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packs_epi16() { + const fn test_mm256_packs_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_packs_epi16(a, b); @@ -5080,7 +5084,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packs_epi32() { + const fn test_mm256_packs_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_packs_epi32(a, b); @@ -5090,7 +5094,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packus_epi16() { + const fn test_mm256_packus_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_packus_epi16(a, b); @@ -5106,7 +5110,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packus_epi32() { + const fn test_mm256_packus_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_packus_epi32(a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 360b755d5818a..8c7921fc18019 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6587,7 +6587,13 @@ pub fn _mm512_maskz_packs_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm256_mask_packs_epi32(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packs_epi32( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packs_epi32(a, b).as_i16x16(); transmute(simd_select_bitmask(k, pack, src.as_i16x16())) @@ -6709,7 +6715,13 @@ pub fn _mm512_maskz_packs_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm256_mask_packs_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packs_epi16( + src: __m256i, + k: __mmask32, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packs_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, src.as_i8x32())) @@ -6723,7 +6735,8 @@ pub fn _mm256_mask_packs_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm256_maskz_packs_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_packs_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let pack = _mm256_packs_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, i8x32::ZERO)) @@ -6831,7 +6844,13 @@ pub fn _mm512_maskz_packus_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm256_mask_packus_epi32(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packus_epi32( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packus_epi32(a, b).as_i16x16(); transmute(simd_select_bitmask(k, pack, src.as_i16x16())) @@ -6845,7 +6864,8 @@ pub fn _mm256_mask_packus_epi32(src: __m256i, k: __mmask16, a: __m256i, b: __m25 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm256_maskz_packus_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_packus_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let pack = _mm256_packus_epi32(a, b).as_i16x16(); transmute(simd_select_bitmask(k, pack, i16x16::ZERO)) @@ -6953,7 +6973,13 @@ pub fn _mm512_maskz_packus_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm256_mask_packus_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packus_epi16( + src: __m256i, + k: __mmask32, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packus_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, src.as_i8x32())) @@ -6967,7 +6993,8 @@ pub fn _mm256_mask_packus_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m25 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm256_maskz_packus_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_packus_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let pack = _mm256_packus_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, i8x32::ZERO)) @@ -17838,7 +17865,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packs_epi32() { + const fn test_mm256_mask_packs_epi32() { let a = _mm256_set1_epi32(i32::MAX); let b = _mm256_set1_epi32(1 << 16 | 1); let r = _mm256_mask_packs_epi32(a, 0, a, b); @@ -17936,7 +17963,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packs_epi16() { + const fn test_mm256_mask_packs_epi16() { let a = _mm256_set1_epi16(i16::MAX); let b = _mm256_set1_epi16(1 << 8 | 1); let r = _mm256_mask_packs_epi16(a, 0, a, b); @@ -17949,7 +17976,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_maskz_packs_epi16() { + const fn test_mm256_maskz_packs_epi16() { let a = _mm256_set1_epi16(i16::MAX); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_packs_epi16(0, a, b); @@ -18023,7 +18050,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packus_epi32() { + const fn test_mm256_mask_packus_epi32() { let a = _mm256_set1_epi32(-1); let b = _mm256_set1_epi32(1 << 16 | 1); let r = _mm256_mask_packus_epi32(a, 0, a, b); @@ -18034,7 +18061,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_maskz_packus_epi32() { + const fn test_mm256_maskz_packus_epi32() { let a = _mm256_set1_epi32(-1); let b = _mm256_set1_epi32(1); let r = _mm256_maskz_packus_epi32(0, a, b); @@ -18119,7 +18146,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packus_epi16() { + const fn test_mm256_mask_packus_epi16() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(1 << 8 | 1); let r = _mm256_mask_packus_epi16(a, 0, a, b); @@ -18132,7 +18159,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_maskz_packus_epi16() { + const fn test_mm256_maskz_packus_epi16() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_packus_epi16(0, a, b); From 37bd99e2e0992495589c330d7478ec00f2dd8b85 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 20 Feb 2026 07:30:10 -0500 Subject: [PATCH 13/35] Add const to `avx512bw` intrinsics --- .../crates/core_arch/src/x86/avx512bw.rs | 96 ++++++++++++------- 1 file changed, 64 insertions(+), 32 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 8c7921fc18019..b41f8576cfe54 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6523,10 +6523,11 @@ pub fn _mm_maskz_maddubs_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm512_packs_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packs_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { - let max = simd_splat(i32::from(i16::MAX)); - let min = simd_splat(i32::from(i16::MIN)); + let max = simd_splat(i16::MAX as i32); + let min = simd_splat(i16::MIN as i32); let clamped_a = simd_imax(simd_imin(a.as_i32x16(), max), min) .as_m512i() @@ -6559,7 +6560,13 @@ pub fn _mm512_packs_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm512_mask_packs_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packs_epi32( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packs_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, src.as_i16x32())) @@ -6573,7 +6580,8 @@ pub fn _mm512_mask_packs_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m512 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm512_maskz_packs_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packs_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packs_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, i16x32::ZERO)) @@ -6651,10 +6659,11 @@ pub const fn _mm_maskz_packs_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m12 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm512_packs_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packs_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { - let max = simd_splat(i16::from(i8::MAX)); - let min = simd_splat(i16::from(i8::MIN)); + let max = simd_splat(i8::MAX as i16); + let min = simd_splat(i8::MIN as i16); let clamped_a = simd_imax(simd_imin(a.as_i16x32(), max), min) .as_m512i() @@ -6687,7 +6696,13 @@ pub fn _mm512_packs_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm512_mask_packs_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packs_epi16( + src: __m512i, + k: __mmask64, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packs_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, src.as_i8x64())) @@ -6701,7 +6716,8 @@ pub fn _mm512_mask_packs_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m512 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm512_maskz_packs_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packs_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packs_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, i8x64::ZERO)) @@ -6780,10 +6796,11 @@ pub const fn _mm_maskz_packs_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m1 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm512_packus_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packus_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { - let max = simd_splat(i32::from(u16::MAX)); - let min = simd_splat(i32::from(u16::MIN)); + let max = simd_splat(u16::MAX as i32); + let min = simd_splat(u16::MIN as i32); let clamped_a = simd_imax(simd_imin(a.as_i32x16(), max), min) .as_m512i() @@ -6816,7 +6833,13 @@ pub fn _mm512_packus_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm512_mask_packus_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packus_epi32( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packus_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, src.as_i16x32())) @@ -6830,7 +6853,8 @@ pub fn _mm512_mask_packus_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m51 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm512_maskz_packus_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packus_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packus_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, i16x32::ZERO)) @@ -6909,10 +6933,11 @@ pub const fn _mm_maskz_packus_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m1 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm512_packus_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packus_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { - let max = simd_splat(i16::from(u8::MAX)); - let min = simd_splat(i16::from(u8::MIN)); + let max = simd_splat(u8::MAX as i16); + let min = simd_splat(u8::MIN as i16); let clamped_a = simd_imax(simd_imin(a.as_i16x32(), max), min) .as_m512i() @@ -6945,7 +6970,13 @@ pub fn _mm512_packus_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm512_mask_packus_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packus_epi16( + src: __m512i, + k: __mmask64, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packus_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, src.as_i8x64())) @@ -6959,7 +6990,8 @@ pub fn _mm512_mask_packus_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m51 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm512_maskz_packus_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packus_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packus_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, i8x64::ZERO)) @@ -17828,7 +17860,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packs_epi32() { + const fn test_mm512_packs_epi32() { let a = _mm512_set1_epi32(i32::MAX); let b = _mm512_set1_epi32(1); let r = _mm512_packs_epi32(a, b); @@ -17839,7 +17871,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packs_epi32() { + const fn test_mm512_mask_packs_epi32() { let a = _mm512_set1_epi32(i32::MAX); let b = _mm512_set1_epi32(1 << 16 | 1); let r = _mm512_mask_packs_epi32(a, 0, a, b); @@ -17852,7 +17884,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packs_epi32() { + const fn test_mm512_maskz_packs_epi32() { let a = _mm512_set1_epi32(i32::MAX); let b = _mm512_set1_epi32(1); let r = _mm512_maskz_packs_epi32(0, a, b); @@ -17911,7 +17943,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packs_epi16() { + const fn test_mm512_packs_epi16() { let a = _mm512_set1_epi16(i16::MAX); let b = _mm512_set1_epi16(1); let r = _mm512_packs_epi16(a, b); @@ -17924,7 +17956,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packs_epi16() { + const fn test_mm512_mask_packs_epi16() { let a = _mm512_set1_epi16(i16::MAX); let b = _mm512_set1_epi16(1 << 8 | 1); let r = _mm512_mask_packs_epi16(a, 0, a, b); @@ -17944,7 +17976,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packs_epi16() { + const fn test_mm512_maskz_packs_epi16() { let a = _mm512_set1_epi16(i16::MAX); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_packs_epi16(0, a, b); @@ -18013,7 +18045,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packus_epi32() { + const fn test_mm512_packus_epi32() { let a = _mm512_set1_epi32(-1); let b = _mm512_set1_epi32(1); let r = _mm512_packus_epi32(a, b); @@ -18024,7 +18056,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packus_epi32() { + const fn test_mm512_mask_packus_epi32() { let a = _mm512_set1_epi32(-1); let b = _mm512_set1_epi32(1 << 16 | 1); let r = _mm512_mask_packus_epi32(a, 0, a, b); @@ -18037,7 +18069,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packus_epi32() { + const fn test_mm512_maskz_packus_epi32() { let a = _mm512_set1_epi32(-1); let b = _mm512_set1_epi32(1); let r = _mm512_maskz_packus_epi32(0, a, b); @@ -18094,7 +18126,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packus_epi16() { + const fn test_mm512_packus_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(1); let r = _mm512_packus_epi16(a, b); @@ -18107,7 +18139,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packus_epi16() { + const fn test_mm512_mask_packus_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(1 << 8 | 1); let r = _mm512_mask_packus_epi16(a, 0, a, b); @@ -18127,7 +18159,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packus_epi16() { + const fn test_mm512_maskz_packus_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_packus_epi16(0, a, b); From 47ef7f73de0547680678ef1184ed1f6889e69614 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 23 Feb 2026 11:58:18 +0100 Subject: [PATCH 14/35] aarch64: cleanup of some long array literals --- .../core_arch/src/aarch64/neon/generated.rs | 539 ++---------------- .../spec/neon/aarch64.spec.yml | 108 ++-- 2 files changed, 108 insertions(+), 539 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 41f01d445fc71..de64839661d6e 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -14131,26 +14131,7 @@ pub fn vmlaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlal_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s16)"] @@ -14165,26 +14146,7 @@ pub fn vmlal_high_laneq_s16( c: int16x8_t, ) -> int32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlal_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_s32)"] @@ -14195,13 +14157,7 @@ pub fn vmlal_high_laneq_s16( #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlal_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlal_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s32)"] @@ -14216,13 +14172,7 @@ pub fn vmlal_high_laneq_s32( c: int32x4_t, ) -> int64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u16)"] @@ -14237,26 +14187,7 @@ pub fn vmlal_high_lane_u16( c: uint16x4_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u16)"] @@ -14271,26 +14202,7 @@ pub fn vmlal_high_laneq_u16( c: uint16x8_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlal_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u32)"] @@ -14305,13 +14217,7 @@ pub fn vmlal_high_lane_u32( c: uint32x2_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlal_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u32)"] @@ -14326,13 +14232,7 @@ pub fn vmlal_high_laneq_u32( c: uint32x4_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_s16)"] @@ -14475,26 +14375,7 @@ pub fn vmlsq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlsl_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s16)"] @@ -14509,26 +14390,7 @@ pub fn vmlsl_high_laneq_s16( c: int16x8_t, ) -> int32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlsl_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_s32)"] @@ -14539,13 +14401,7 @@ pub fn vmlsl_high_laneq_s16( #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlsl_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlsl_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s32)"] @@ -14560,13 +14416,7 @@ pub fn vmlsl_high_laneq_s32( c: int32x4_t, ) -> int64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u16)"] @@ -14581,26 +14431,7 @@ pub fn vmlsl_high_lane_u16( c: uint16x4_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u16)"] @@ -14615,26 +14446,7 @@ pub fn vmlsl_high_laneq_u16( c: uint16x8_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlsl_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u32)"] @@ -14649,13 +14461,7 @@ pub fn vmlsl_high_lane_u32( c: uint32x2_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlsl_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u32)"] @@ -14670,13 +14476,7 @@ pub fn vmlsl_high_laneq_u32( c: uint32x4_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_s16)"] @@ -14975,12 +14775,7 @@ pub fn vmul_lane_f64(a: float64x1_t, b: float64x1_t) -> float64 #[cfg(not(target_arch = "arm64ec"))] pub fn vmul_laneq_f16(a: float16x4_t, b: float16x8_t) -> float16x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - simd_mul( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f16)"] @@ -14992,25 +14787,7 @@ pub fn vmul_laneq_f16(a: float16x4_t, b: float16x8_t) -> float1 #[cfg(not(target_arch = "arm64ec"))] pub fn vmulq_laneq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - simd_mul( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_f64)"] @@ -15104,25 +14881,7 @@ pub fn vmulh_laneq_f16(a: f16, b: float16x8_t) -> f16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_s16(a: int16x8_t, b: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_s16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_s16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s16)"] @@ -15133,25 +14892,7 @@ pub fn vmull_high_lane_s16(a: int16x8_t, b: int16x4_t) -> int32 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmull_high_s16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_s16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_s32)"] @@ -15162,12 +14903,7 @@ pub fn vmull_high_laneq_s16(a: int16x8_t, b: int16x8_t) -> int3 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_s32(a: int32x4_t, b: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmull_high_s32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_s32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s32)"] @@ -15178,12 +14914,7 @@ pub fn vmull_high_lane_s32(a: int32x4_t, b: int32x2_t) -> int64 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_s32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_s32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u16)"] @@ -15194,25 +14925,7 @@ pub fn vmull_high_laneq_s32(a: int32x4_t, b: int32x4_t) -> int6 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_u16(a: uint16x8_t, b: uint16x4_t) -> uint32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_u16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_u16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u16)"] @@ -15223,25 +14936,7 @@ pub fn vmull_high_lane_u16(a: uint16x8_t, b: uint16x4_t) -> uin #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmull_high_u16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_u16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u32)"] @@ -15252,12 +14947,7 @@ pub fn vmull_high_laneq_u16(a: uint16x8_t, b: uint16x8_t) -> ui #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_u32(a: uint32x4_t, b: uint32x2_t) -> uint64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmull_high_u32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_u32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u32)"] @@ -15268,12 +14958,7 @@ pub fn vmull_high_lane_u32(a: uint32x4_t, b: uint32x2_t) -> uin #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_u32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_u32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_s16)"] @@ -15436,7 +15121,7 @@ pub fn vmull_p64(a: p64, b: p64) -> p128 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulq_lane_f64(a: float64x2_t, b: float64x1_t) -> float64x2_t { static_assert!(LANE == 0); - unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f64)"] @@ -15447,7 +15132,7 @@ pub fn vmulq_lane_f64(a: float64x2_t, b: float64x1_t) -> float6 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulq_laneq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuls_lane_f32)"] @@ -15599,12 +15284,7 @@ pub fn vmulxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vmulx_lane_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmulx_f16( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulx_f16(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f16)"] @@ -15616,12 +15296,7 @@ pub fn vmulx_lane_f16(a: float16x4_t, b: float16x4_t) -> float1 #[cfg(not(target_arch = "arm64ec"))] pub fn vmulx_laneq_f16(a: float16x4_t, b: float16x8_t) -> float16x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmulx_f16( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulx_f16(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f16)"] @@ -15633,25 +15308,7 @@ pub fn vmulx_laneq_f16(a: float16x4_t, b: float16x8_t) -> float #[cfg(not(target_arch = "arm64ec"))] pub fn vmulxq_lane_f16(a: float16x8_t, b: float16x4_t) -> float16x8_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmulxq_f16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmulxq_f16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f16)"] @@ -15663,25 +15320,7 @@ pub fn vmulxq_lane_f16(a: float16x8_t, b: float16x4_t) -> float #[cfg(not(target_arch = "arm64ec"))] pub fn vmulxq_laneq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmulxq_f16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmulxq_f16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f32)"] @@ -15692,7 +15331,7 @@ pub fn vmulxq_laneq_f16(a: float16x8_t, b: float16x8_t) -> floa #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulx_lane_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f32)"] @@ -15703,7 +15342,7 @@ pub fn vmulx_lane_f32(a: float32x2_t, b: float32x2_t) -> float3 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulx_laneq_f32(a: float32x2_t, b: float32x4_t) -> float32x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f32)"] @@ -15714,12 +15353,7 @@ pub fn vmulx_laneq_f32(a: float32x2_t, b: float32x4_t) -> float #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_lane_f32(a: float32x4_t, b: float32x2_t) -> float32x4_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmulxq_f32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulxq_f32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f32)"] @@ -15730,12 +15364,7 @@ pub fn vmulxq_lane_f32(a: float32x4_t, b: float32x2_t) -> float #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_laneq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmulxq_f32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulxq_f32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f64)"] @@ -15746,7 +15375,7 @@ pub fn vmulxq_laneq_f32(a: float32x4_t, b: float32x4_t) -> floa #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_laneq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f64)"] @@ -15916,7 +15545,7 @@ pub fn vmulxh_laneq_f16(a: f16, b: float16x8_t) -> f16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_lane_f64(a: float64x2_t, b: float64x1_t) -> float64x2_t { static_assert!(LANE == 0); - unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Negate"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_f64)"] @@ -17916,8 +17545,7 @@ pub fn vqnegd_s64(a: i64) -> i64 { pub fn vqrdmlah_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlah_s16(a, b, c) } } @@ -17931,7 +17559,7 @@ pub fn vqrdmlah_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4 pub fn vqrdmlah_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlah_s32(a, b, c) } } @@ -17945,8 +17573,7 @@ pub fn vqrdmlah_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2 pub fn vqrdmlah_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x8_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlah_s16(a, b, c) } } @@ -17960,7 +17587,7 @@ pub fn vqrdmlah_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x pub fn vqrdmlah_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x4_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlah_s32(a, b, c) } } @@ -17974,20 +17601,7 @@ pub fn vqrdmlah_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x pub fn vqrdmlahq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x4_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlahq_s16(a, b, c) } } @@ -18001,8 +17615,7 @@ pub fn vqrdmlahq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x pub fn vqrdmlahq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x2_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlahq_s32(a, b, c) } } @@ -18016,20 +17629,7 @@ pub fn vqrdmlahq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x pub fn vqrdmlahq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlahq_s16(a, b, c) } } @@ -18043,8 +17643,7 @@ pub fn vqrdmlahq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16 pub fn vqrdmlahq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlahq_s32(a, b, c) } } @@ -18190,8 +17789,7 @@ pub fn vqrdmlahs_s32(a: i32, b: i32, c: i32) -> i32 { pub fn vqrdmlsh_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlsh_s16(a, b, c) } } @@ -18205,7 +17803,7 @@ pub fn vqrdmlsh_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4 pub fn vqrdmlsh_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlsh_s32(a, b, c) } } @@ -18219,8 +17817,7 @@ pub fn vqrdmlsh_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2 pub fn vqrdmlsh_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x8_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlsh_s16(a, b, c) } } @@ -18234,7 +17831,7 @@ pub fn vqrdmlsh_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x pub fn vqrdmlsh_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x4_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlsh_s32(a, b, c) } } @@ -18248,20 +17845,7 @@ pub fn vqrdmlsh_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x pub fn vqrdmlshq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x4_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlshq_s16(a, b, c) } } @@ -18275,8 +17859,7 @@ pub fn vqrdmlshq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x pub fn vqrdmlshq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x2_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlshq_s32(a, b, c) } } @@ -18290,20 +17873,7 @@ pub fn vqrdmlshq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x pub fn vqrdmlshq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlshq_s16(a, b, c) } } @@ -18317,8 +17887,7 @@ pub fn vqrdmlshq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16 pub fn vqrdmlshq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlshq_s32(a, b, c) } } diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index 0ec8024fdfbb6..8574aacee6671 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -5374,7 +5374,7 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - ["q_lane_f64", float64x2_t, float64x1_t, "q_f64", '[LANE as u32, LANE as u32]'] + - ["q_lane_f64", float64x2_t, float64x1_t, "q_f64", '[LANE as u32; 2]'] compose: - FnCall: [static_assert!, ['LANE == 0']] - FnCall: @@ -5443,11 +5443,11 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - ['_lane_f32', float32x2_t, float32x2_t, '1', '_f32', '[LANE as u32, LANE as u32]'] - - ['_laneq_f32', float32x2_t, float32x4_t, '2', '_f32', '[LANE as u32, LANE as u32]'] - - ['q_lane_f32', float32x4_t, float32x2_t, '1', 'q_f32', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_laneq_f32', float32x4_t, float32x4_t, '2', 'q_f32', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_laneq_f64', float64x2_t, float64x2_t, '1', 'q_f64', '[LANE as u32, LANE as u32]'] + - ['_lane_f32', float32x2_t, float32x2_t, '1', '_f32', '[LANE as u32; 2]'] + - ['_laneq_f32', float32x2_t, float32x4_t, '2', '_f32', '[LANE as u32; 2]'] + - ['q_lane_f32', float32x4_t, float32x2_t, '1', 'q_f32', '[LANE as u32; 4]'] + - ['q_laneq_f32', float32x4_t, float32x4_t, '2', 'q_f32', '[LANE as u32; 4]'] + - ['q_laneq_f64', float64x2_t, float64x2_t, '1', 'q_f64', '[LANE as u32; 2]'] compose: - FnCall: [static_assert_uimm_bits!, ['LANE', "{type[3]}"]] - FnCall: @@ -5473,10 +5473,10 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - ['_lane_f16', float16x4_t, float16x4_t, '2', '_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['_laneq_f16', float16x4_t, float16x8_t, '3', '_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_lane_f16', float16x8_t, float16x4_t, '2', 'q_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_laneq_f16', float16x8_t, float16x8_t, '3', 'q_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - ['_lane_f16', float16x4_t, float16x4_t, '2', '_f16', '[LANE as u32; 4]'] + - ['_laneq_f16', float16x4_t, float16x8_t, '3', '_f16', '[LANE as u32; 4]'] + - ['q_lane_f16', float16x8_t, float16x4_t, '2', 'q_f16', '[LANE as u32; 8]'] + - ['q_laneq_f16', float16x8_t, float16x8_t, '3', 'q_f16', '[LANE as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, ['LANE', "{type[3]}"]] - FnCall: @@ -7755,14 +7755,14 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]'] - - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]'] - - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32; 4]'] + - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32; 4]'] + - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32; 2]'] + - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32; 2]'] + - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[4]}']] - Let: [c, "{type[1]}", {FnCall: [simd_shuffle!, [c, c, "{type[5]}"]]}] @@ -7839,14 +7839,14 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]'] - - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]'] - - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32; 4]'] + - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32; 4]'] + - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32; 2]'] + - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32; 2]'] + - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[4]}']] - Let: [c, "{type[1]}", {FnCall: [simd_shuffle!, [c, c, "{type[5]}"]]}] @@ -11138,7 +11138,7 @@ intrinsics: - FnCall: - simd_mul - - a - - FnCall: ["simd_shuffle!", [b, b, '[LANE as u32, LANE as u32]']] + - FnCall: ["simd_shuffle!", [b, b, '[LANE as u32; 2]']] - name: "vmuld_lane_f64" doc: "Floating-point multiply" @@ -11195,7 +11195,7 @@ intrinsics: - FnCall: - simd_mul - - a - - FnCall: [simd_shuffle!, [b, b, '[LANE as u32, LANE as u32]']] + - FnCall: [simd_shuffle!, [b, b, '[LANE as u32; 2]']] # vmulq_laneq_f16 @@ -11212,8 +11212,8 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [float16x4_t, float16x8_t, '_lane', "[LANE as u32, LANE as u32, LANE as u32, LANE as u32]"] - - [float16x8_t, float16x8_t, 'q_lane', "[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]"] + - [float16x4_t, float16x8_t, '_lane', "[LANE as u32; 4]"] + - [float16x8_t, float16x8_t, 'q_lane', "[LANE as u32; 8]"] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '3']] - FnCall: @@ -11335,10 +11335,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: @@ -11358,10 +11358,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32; 8]'] + - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32; 8]'] + - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32; 4]'] + - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: @@ -11660,10 +11660,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [int16x8_t, int16x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int16x8_t, int16x8_t, int32x4_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int32x2_t, int64x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int32x4_t, int64x2_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int16x8_t, int16x4_t, int32x4_t, '2', '[LANE as u32; 8]'] + - [int16x8_t, int16x8_t, int32x4_t, '3', '[LANE as u32; 8]'] + - [int32x4_t, int32x2_t, int64x2_t, '1', '[LANE as u32; 4]'] + - [int32x4_t, int32x4_t, int64x2_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]] - FnCall: @@ -11682,10 +11682,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [uint16x8_t, uint16x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint16x8_t, uint16x8_t, uint32x4_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint32x2_t, uint64x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint32x4_t, uint64x2_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint16x8_t, uint16x4_t, uint32x4_t, '2', '[LANE as u32; 8]'] + - [uint16x8_t, uint16x8_t, uint32x4_t, '3', '[LANE as u32; 8]'] + - [uint32x4_t, uint32x2_t, uint64x2_t, '1', '[LANE as u32; 4]'] + - [uint32x4_t, uint32x4_t, uint64x2_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]] - FnCall: @@ -11973,10 +11973,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: ['vmlal_high_{neon_type[2]}', [a, b, {FnCall: [simd_shuffle!, [c, c, '{type[4]}']]}]] @@ -11992,10 +11992,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32; 8]'] + - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32; 8]'] + - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32; 4]'] + - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: ['vmlal_high_{neon_type[2]}', [a, b, {FnCall: [simd_shuffle!, [c, c, '{type[4]}']]}]] From 820ca4803853f80be0dbd29e31a82f623107e769 Mon Sep 17 00:00:00 2001 From: sayantn Date: Wed, 25 Feb 2026 04:49:15 +0530 Subject: [PATCH 15/35] Update Intel SDE version to 10.5 --- library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile | 2 +- library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile index 2743896375cf3..a357449d51e3d 100644 --- a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile +++ b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -12,7 +12,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ lld -RUN wget http://ci-mirrors.rust-lang.org/stdarch/sde-external-9.58.0-2025-06-16-lin.tar.xz -O sde.tar.xz +RUN wget http://ci-mirrors.rust-lang.org/stdarch/sde-external-10.5.0-2026-01-13-lin.tar.xz -O sde.tar.xz RUN mkdir intel-sde RUN tar -xJf sde.tar.xz --strip-components=1 -C intel-sde ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="/intel-sde/sde64 \ diff --git a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def index 342f7d83a63e3..acf023ed0dc49 100644 --- a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def +++ b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def @@ -12,7 +12,7 @@ # CPUID_VERSION = 1.0 # Input => Output # EAX ECX => EAX EBX ECX EDX -00000000 ******** => 00000024 756e6547 6c65746e 49656e69 +00000000 ******** => 00000029 756e6547 6c65746e 49656e69 00000001 ******** => 00400f10 00100800 7ffaf3ff bfebfbff 00000002 ******** => 76035a01 00f0b6ff 00000000 00c10000 00000003 ******** => 00000000 00000000 00000000 00000000 @@ -48,6 +48,7 @@ 0000001e 00000001 => 000001ff 00000000 00000000 00000000 00000024 00000000 => 00000001 00070002 00000000 00000000 #AVX10 00000024 00000001 => 00000000 00000000 00000004 00000000 +00000029 ******** => 00000000 00000001 00000000 00000000 80000000 ******** => 80000008 00000000 00000000 00000000 80000001 ******** => 00000000 00000000 00000121 2c100000 80000002 ******** => 00000000 00000000 00000000 00000000 From f01bcce3e22cf232d25db92335e6fbaa3f6daaf1 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 25 Feb 2026 15:00:04 +0100 Subject: [PATCH 16/35] update to `resolver = 3` --- library/stdarch/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch/Cargo.toml b/library/stdarch/Cargo.toml index 5979096439118..e3963a69879a1 100644 --- a/library/stdarch/Cargo.toml +++ b/library/stdarch/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "1" +resolver = "3" members = [ "crates/*", "examples", From cb3046e5f2f0736366c0fea4977a8df579d96311 Mon Sep 17 00:00:00 2001 From: ArunTamil21 Date: Wed, 25 Feb 2026 23:56:42 +0000 Subject: [PATCH 17/35] Add missing runtime test for _mm_comige_ss and fix _mm_comigt_ss test --- .../stdarch/crates/core_arch/src/x86/sse.rs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 2c4439a3f3a55..3f7781cc7dc4c 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -2816,14 +2816,32 @@ mod tests { let aa = &[3.0f32, 12.0, 23.0, NAN]; let bb = &[3.0f32, 47.5, 1.5, NAN]; - let ee = &[1i32, 0, 1, 0]; + let ee = &[0i32, 0, 1, 0]; for i in 0..4 { let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0); let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0); - let r = _mm_comige_ss(a, b); + let r = _mm_comigt_ss(a, b); + assert_eq!( + ee[i], r, + "_mm_comigt_ss({:?}, {:?}) = {}, expected: {} (i={})", + a, b, r, ee[i], i + ); + } + } + + #[simd_test(enable = "sse")] + fn test_mm_comige_ss() { + let aa = &[3.0f32, 23.0, 12.0, NAN]; + let bb = &[3.0f32, 1.5, 47.5, NAN]; + let ee = &[1i32, 1, 0, 0]; + + for i in 0..4 { + let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0); + let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0); + let r = _mm_comige_ss(a, b); assert_eq!( ee[i], r, "_mm_comige_ss({:?}, {:?}) = {}, expected: {} (i={})", From f981ffe959bb8a8a99fa02b6864bb82d7b2d170a Mon Sep 17 00:00:00 2001 From: ArunTamil21 Date: Thu, 26 Feb 2026 09:19:29 +0000 Subject: [PATCH 18/35] Remove _mm_comige_ss from skip list in x86-intel.rs --- library/stdarch/crates/stdarch-verify/tests/x86-intel.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs b/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs index 4136463f197fd..2ac05e28cb4ce 100644 --- a/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs +++ b/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs @@ -246,7 +246,6 @@ fn verify_all_signatures() { "_xend", "_xabort_code", // Aliases - "_mm_comige_ss", "_mm_cvt_ss2si", "_mm_cvtt_ss2si", "_mm_cvt_si2ss", From 2fa37e7b3498a9cb46004fae5fd9d6d40835ad28 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 26 Feb 2026 13:00:21 +0100 Subject: [PATCH 19/35] aarch64: fix UB in non-power-of-two reads and writes --- .../stdarch/crates/core_arch/src/macros.rs | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/macros.rs b/library/stdarch/crates/core_arch/src/macros.rs index 5a582fe17772b..00e92428b3e7e 100644 --- a/library/stdarch/crates/core_arch/src/macros.rs +++ b/library/stdarch/crates/core_arch/src/macros.rs @@ -237,12 +237,12 @@ macro_rules! deinterleaving_load { ($elem:ty, $lanes:literal, 2, $ptr:expr) => {{ use $crate::core_arch::macros::deinterleave_mask; use $crate::core_arch::simd::Simd; - use $crate::{mem::transmute, ptr}; + use $crate::mem::transmute; type V = Simd<$elem, $lanes>; type W = Simd<$elem, { $lanes * 2 }>; - let w: W = ptr::read_unaligned($ptr as *const W); + let w: W = $crate::ptr::read_unaligned($ptr as *const W); let v0: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 2, 0>()); let v1: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 2, 1>()); @@ -253,12 +253,20 @@ macro_rules! deinterleaving_load { ($elem:ty, $lanes:literal, 3, $ptr:expr) => {{ use $crate::core_arch::macros::deinterleave_mask; use $crate::core_arch::simd::Simd; - use $crate::{mem::transmute, ptr}; + use $crate::mem::{MaybeUninit, transmute}; type V = Simd<$elem, $lanes>; type W = Simd<$elem, { $lanes * 3 }>; - let w: W = ptr::read_unaligned($ptr as *const W); + // NOTE: repr(simd) adds padding to make the total size a power of two. + // Hence reading W from ptr might read out of bounds. + let mut mem = MaybeUninit::::uninit(); + $crate::ptr::copy_nonoverlapping( + $ptr.cast::<$elem>(), + mem.as_mut_ptr().cast::<$elem>(), + $lanes * 3, + ); + let w = mem.assume_init(); let v0: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 3, 0>()); let v1: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 3, 1>()); @@ -270,12 +278,12 @@ macro_rules! deinterleaving_load { ($elem:ty, $lanes:literal, 4, $ptr:expr) => {{ use $crate::core_arch::macros::deinterleave_mask; use $crate::core_arch::simd::Simd; - use $crate::{mem::transmute, ptr}; + use $crate::mem::transmute; type V = Simd<$elem, $lanes>; type W = Simd<$elem, { $lanes * 4 }>; - let w: W = ptr::read_unaligned($ptr as *const W); + let w: W = $crate::ptr::read_unaligned($ptr as *const W); let v0: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 4, 0>()); let v1: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 4, 1>()); @@ -322,8 +330,15 @@ macro_rules! interleaving_store { simd_shuffle!($v.2, $v.2, identity::<{ $lanes * 2 }>()); type W = Simd<$elem, { $lanes * 3 }>; + + // NOTE: repr(simd) adds padding to make the total size a power of two. + // Hence writing W to ptr might write out of bounds. let w: W = simd_shuffle!(v0v1, v2v2, interleave_mask::<{ $lanes * 3 }, $lanes, 3>()); - $crate::ptr::write_unaligned($ptr as *mut W, w); + $crate::ptr::copy_nonoverlapping( + (&w as *const W).cast::<$elem>(), + $ptr.cast::<$elem>(), + $lanes * 3, + ); }}; // N = 4 From a0ccef6f25b342253027a9c1586af0f944740b6f Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:15:15 +0900 Subject: [PATCH 20/35] Add `impl_restriction` feature --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + 3 files changed, 4 insertions(+) diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index c955ada05b09a..72679d7456659 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -590,6 +590,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(coroutines, "coroutine syntax is experimental"); gate_all!(const_block_items, "const block items are experimental"); gate_all!(final_associated_functions, "`final` on trait functions is experimental"); + gate_all!(impl_restriction, "`impl` restrictions are experimental"); if !visitor.features.never_patterns() { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 1d123385961aa..bedfa2c3123ad 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -516,6 +516,8 @@ declare_features! ( (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)), /// Target features on hexagon. (unstable, hexagon_target_feature, "1.27.0", Some(150250)), + /// Allows `impl(crate) trait Foo` restrictions. + (incomplete, impl_restriction, "CURRENT_RUSTC_VERSION", Some(105077)), /// Allows `impl Trait` to be used inside associated types (RFC 2515). (unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)), /// Allows `impl Trait` in bindings (`let`). diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 731a838530729..0538c6002f7f2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1068,6 +1068,7 @@ symbols! { immediate_abort: "immediate-abort", impl_header_lifetime_elision, impl_lint_pass, + impl_restriction, impl_trait_in_assoc_type, impl_trait_in_bindings, impl_trait_in_fn_trait_return, From 3232d992e304820a463e6c22df44289c71e87a7b Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:17:27 +0900 Subject: [PATCH 21/35] Introduce `impl` restriction to AST --- compiler/rustc_ast/src/ast.rs | 14 ++++++++++++++ compiler/rustc_ast/src/ast_traits.rs | 20 ++++++++++++++++---- compiler/rustc_ast/src/visit.rs | 3 +++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 026758958f04f..9241da816e050 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3542,6 +3542,19 @@ impl VisibilityKind { } } +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct ImplRestriction { + pub kind: RestrictionKind, + pub span: Span, + pub tokens: Option, +} + +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub enum RestrictionKind { + Unrestricted, + Restricted { path: Box, id: NodeId, shorthand: bool }, +} + /// Field definition in a struct, variant or union. /// /// E.g., `bar: usize` as in `struct Foo { bar: usize }`. @@ -3741,6 +3754,7 @@ pub struct Trait { pub constness: Const, pub safety: Safety, pub is_auto: IsAuto, + pub impl_restriction: ImplRestriction, pub ident: Ident, pub generics: Generics, #[visitable(extra = BoundKind::SuperTraits)] diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 3d2477e5f033f..73bfa0ba7ab6d 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -8,8 +8,8 @@ use std::marker::PhantomData; use crate::tokenstream::LazyAttrTokenStream; use crate::{ Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField, - FieldDef, ForeignItem, GenericParam, Item, NodeId, Param, Pat, PatField, Path, Stmt, StmtKind, - Ty, Variant, Visibility, WherePredicate, + FieldDef, ForeignItem, GenericParam, ImplRestriction, Item, NodeId, Param, Pat, PatField, Path, + Stmt, StmtKind, Ty, Variant, Visibility, WherePredicate, }; /// A trait for AST nodes having an ID. @@ -97,7 +97,19 @@ macro_rules! impl_has_tokens_none { }; } -impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, Ty, Visibility); +impl_has_tokens!( + AssocItem, + AttrItem, + Block, + Expr, + ForeignItem, + Item, + Pat, + Path, + Ty, + Visibility, + ImplRestriction +); impl_has_tokens_none!( Arm, ExprField, @@ -242,7 +254,7 @@ impl_has_attrs!( Variant, WherePredicate, ); -impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility); +impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility, ImplRestriction); impl HasAttrs for Box { const SUPPORTS_CUSTOM_INNER_ATTRS: bool = T::SUPPORTS_CUSTOM_INNER_ATTRS; diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ff389607457d4..e7b492a9c1db5 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -467,6 +467,7 @@ macro_rules! common_visitor_and_walkers { RangeEnd, RangeSyntax, Recovered, + RestrictionKind, Safety, StaticItem, StrLit, @@ -595,6 +596,7 @@ macro_rules! common_visitor_and_walkers { fn visit_poly_trait_ref(PolyTraitRef); fn visit_precise_capturing_arg(PreciseCapturingArg); fn visit_qself(QSelf); + fn visit_impl_restriction(ImplRestriction); fn visit_trait_ref(TraitRef); fn visit_ty_pat(TyPat); fn visit_ty(Ty); @@ -1117,6 +1119,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_poly_trait_ref(PolyTraitRef); pub fn walk_precise_capturing_arg(PreciseCapturingArg); pub fn walk_qself(QSelf); + pub fn walk_impl_restriction(ImplRestriction); pub fn walk_trait_ref(TraitRef); pub fn walk_ty_pat(TyPat); pub fn walk_ty(Ty); From f55f6b4451df457dd22f1b98b4f44502258b2d5c Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:24:19 +0900 Subject: [PATCH 22/35] Parse `impl` restriction on trait definitions --- compiler/rustc_parse/src/errors.rs | 20 ++++++ compiler/rustc_parse/src/parser/item.rs | 81 ++++++++++++++++++++++--- compiler/rustc_parse/src/parser/mod.rs | 64 ++++++++++++++++++- 3 files changed, 154 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index cefd0e35f8a5c..15e7fe805845a 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1268,6 +1268,26 @@ pub(crate) struct IncorrectVisibilityRestriction { pub inner_str: String, } +#[derive(Diagnostic)] +#[diag("incorrect `impl` restriction")] +#[help( + "some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path" +)] +pub(crate) struct IncorrectImplRestriction { + #[primary_span] + #[suggestion( + "help: use `in` to restrict implementations to the path `{$inner_str}`", + code = "in {inner_str}", + applicability = "machine-applicable" + )] + pub span: Span, + pub inner_str: String, +} + #[derive(Diagnostic)] #[diag(" ... else {\"{\"} ... {\"}\"} is not allowed")] pub(crate) struct AssignmentElseNotAllowed { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3421924d1f762..37e03ddbab127 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1025,17 +1025,79 @@ impl<'a> Parser<'a> { } } - /// Is this an `(const unsafe? auto?| unsafe auto? | auto) trait` item? + /// Is there an `[ impl(in? path) ]? trait` item `dist` tokens ahead? + fn is_trait_with_maybe_impl_restriction_in_front(&self, dist: usize) -> bool { + // `trait` + if self.is_keyword_ahead(dist, &[kw::Trait]) { + return true; + } + // `impl(` + if !self.is_keyword_ahead(dist, &[kw::Impl]) + || !self.look_ahead(dist + 1, |t| t == &token::OpenParen) + { + return false; + } + // `crate | super | self) trait` + if self.is_keyword_ahead(dist + 2, &[kw::Crate, kw::Super, kw::SelfLower]) + && self.look_ahead(dist + 3, |t| t == &token::CloseParen) + && self.is_keyword_ahead(dist + 4, &[kw::Trait]) + { + return true; + } + // `impl(in? something) trait` + // We catch cases where the `in` keyword is missing to provide a + // better error message. This is handled later in + // `self.recover_incorrect_impl_restriction`. + self.tree_look_ahead(dist + 2, |t| { + if let TokenTree::Token(token, _) = t { token.is_keyword(kw::Trait) } else { false } + }) + .unwrap_or(false) + } + + /// Is this an `(const unsafe? auto? [ impl(in? path) ]? | unsafe auto? [ impl(in? path) ]? | auto [ impl(in? path) ]? | [ impl(in? path) ]?) trait` item? fn check_trait_front_matter(&mut self) -> bool { - // auto trait - self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait]) - // unsafe auto trait - || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto]) - || self.check_keyword(exp!(Const)) && ((self.is_keyword_ahead(1, &[kw::Trait]) || self.is_keyword_ahead(1, &[kw::Auto]) && self.is_keyword_ahead(2, &[kw::Trait])) - || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto])) + // `[ impl(in? path) ]? trait` + if self.is_trait_with_maybe_impl_restriction_in_front(0) { + return true; + } + // `auto [ impl(in? path) ]? trait` + if self.check_keyword(exp!(Auto)) && self.is_trait_with_maybe_impl_restriction_in_front(1) { + return true; + } + // `unsafe auto? [ impl(in? path) ]? trait` + if self.check_keyword(exp!(Unsafe)) + && (self.is_trait_with_maybe_impl_restriction_in_front(1) + || self.is_keyword_ahead(1, &[kw::Auto]) + && self.is_trait_with_maybe_impl_restriction_in_front(2)) + { + return true; + } + // `const` ... + if !self.check_keyword(exp!(Const)) { + return false; + } + // `const [ impl(in? path) ]? trait` + if self.is_trait_with_maybe_impl_restriction_in_front(1) { + return true; + } + // `const (unsafe | auto) [ impl(in? path) ]? trait` + if self.is_keyword_ahead(1, &[kw::Unsafe, kw::Auto]) + && self.is_trait_with_maybe_impl_restriction_in_front(2) + { + return true; + } + // `const unsafe auto [ impl(in? path) ]? trait` + self.is_keyword_ahead(1, &[kw::Unsafe]) + && self.is_keyword_ahead(2, &[kw::Auto]) + && self.is_trait_with_maybe_impl_restriction_in_front(3) } - /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. + /// Parses `const? unsafe? auto? [impl(in? path)]? trait Foo { ... }` or `trait Foo = Bar;`. + /// + /// FIXME(restrictions): The current keyword order follows the grammar specified in RFC 3323. + /// However, whether the restriction should be grouped closer to the visibility modifier + /// (e.g., `pub impl(crate) const unsafe auto trait`) remains an unresolved design question. + /// This ordering must be kept in sync with the logic in `check_trait_front_matter`. fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> { let constness = self.parse_constness(Case::Sensitive); if let Const::Yes(span) = constness { @@ -1050,6 +1112,8 @@ impl<'a> Parser<'a> { IsAuto::No }; + let impl_restriction = self.parse_impl_restriction()?; + self.expect_keyword(exp!(Trait))?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; @@ -1090,6 +1154,7 @@ impl<'a> Parser<'a> { constness, is_auto, safety, + impl_restriction, ident, generics, bounds, diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index fc8c9813457b6..e18d337354288 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -35,8 +35,9 @@ use rustc_ast::util::case::Case; use rustc_ast::util::classify; use rustc_ast::{ self as ast, AnonConst, AttrArgs, AttrId, BinOpKind, ByRef, Const, CoroutineKind, - DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, MgcaDisambiguation, - Mutability, Recovered, Safety, StrLit, Visibility, VisibilityKind, + DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, ImplRestriction, + MgcaDisambiguation, Mutability, Recovered, RestrictionKind, Safety, StrLit, Visibility, + VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::debug_assert_matches; @@ -50,7 +51,10 @@ use token_type::TokenTypeSet; pub use token_type::{ExpKeywordPair, ExpTokenPair, TokenType}; use tracing::debug; -use crate::errors::{self, IncorrectVisibilityRestriction, NonStringAbiLiteral, TokenDescription}; +use crate::errors::{ + self, IncorrectImplRestriction, IncorrectVisibilityRestriction, NonStringAbiLiteral, + TokenDescription, +}; use crate::exp; #[cfg(test)] @@ -1530,6 +1534,60 @@ impl<'a> Parser<'a> { Ok(()) } + /// Parses an optional `impl` restriction. + /// Enforces the `impl_restriction` feature gate whenever an explicit restriction is encountered. + fn parse_impl_restriction(&mut self) -> PResult<'a, ImplRestriction> { + if self.eat_keyword(exp!(Impl)) { + let lo = self.prev_token.span; + // No units or tuples are allowed to follow `impl` here, so we can safely bump `(`. + self.expect(exp!(OpenParen))?; + if self.eat_keyword(exp!(In)) { + let path = self.parse_path(PathStyle::Mod)?; // `in path` + self.expect(exp!(CloseParen))?; // `)` + let restriction = RestrictionKind::Restricted { + path: Box::new(path), + id: ast::DUMMY_NODE_ID, + shorthand: false, + }; + let span = lo.to(self.prev_token.span); + self.psess.gated_spans.gate(sym::impl_restriction, span); + return Ok(ImplRestriction { kind: restriction, span, tokens: None }); + } else if self.look_ahead(1, |t| t == &token::CloseParen) + && self.is_keyword_ahead(0, &[kw::Crate, kw::Super, kw::SelfLower]) + { + let path = self.parse_path(PathStyle::Mod)?; // `crate`/`super`/`self` + self.expect(exp!(CloseParen))?; // `)` + let restriction = RestrictionKind::Restricted { + path: Box::new(path), + id: ast::DUMMY_NODE_ID, + shorthand: true, + }; + let span = lo.to(self.prev_token.span); + self.psess.gated_spans.gate(sym::impl_restriction, span); + return Ok(ImplRestriction { kind: restriction, span, tokens: None }); + } else { + self.recover_incorrect_impl_restriction(lo)?; + // Emit diagnostic, but continue with no impl restriction. + } + } + Ok(ImplRestriction { + kind: RestrictionKind::Unrestricted, + span: self.token.span.shrink_to_lo(), + tokens: None, + }) + } + + /// Recovery for e.g. `impl(something) trait` + fn recover_incorrect_impl_restriction(&mut self, lo: Span) -> PResult<'a, ()> { + let path = self.parse_path(PathStyle::Mod)?; + self.expect(exp!(CloseParen))?; // `)` + let path_str = pprust::path_to_string(&path); + self.dcx().emit_err(IncorrectImplRestriction { span: path.span, inner_str: path_str }); + let end = self.prev_token.span; + self.psess.gated_spans.gate(sym::impl_restriction, lo.to(end)); + Ok(()) + } + /// Parses `extern string_literal?`. fn parse_extern(&mut self, case: Case) -> Extern { if self.eat_keyword_case(exp!(Extern), case) { From 2b39beaeee4ba69a4d865e55c3cd3ebfc0e5f496 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:25:17 +0900 Subject: [PATCH 23/35] Handle ambiguity between `const unsafe fn` and `const unsafe impl(path) trait` --- compiler/rustc_parse/src/parser/item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 37e03ddbab127..c3b8aac220a80 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2923,8 +2923,8 @@ impl<'a> Parser<'a> { && !self.is_unsafe_foreign_mod() // Rule out `async gen {` and `async gen move {` && !self.is_async_gen_block() - // Rule out `const unsafe auto` and `const unsafe trait`. - && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait]) + // Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`. + && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait, kw::Impl]) ) }) // `extern ABI fn` From 65aef778f837448fc40abb501f0f88d359aa0aca Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:26:56 +0900 Subject: [PATCH 24/35] Pretty print `impl` restriction --- compiler/rustc_ast_pretty/src/pprust/mod.rs | 4 ++++ compiler/rustc_ast_pretty/src/pprust/state.rs | 4 ++++ .../rustc_ast_pretty/src/pprust/state/item.rs | 16 ++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/compiler/rustc_ast_pretty/src/pprust/mod.rs b/compiler/rustc_ast_pretty/src/pprust/mod.rs index 74ed0405498d9..25b398b849246 100644 --- a/compiler/rustc_ast_pretty/src/pprust/mod.rs +++ b/compiler/rustc_ast_pretty/src/pprust/mod.rs @@ -80,6 +80,10 @@ pub fn vis_to_string(v: &ast::Visibility) -> String { State::new().vis_to_string(v) } +pub fn impl_restriction_to_string(r: &ast::ImplRestriction) -> String { + State::new().impl_restriction_to_string(r) +} + pub fn meta_list_item_to_string(li: &ast::MetaItemInner) -> String { State::new().meta_list_item_to_string(li) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index c8874ed99dca9..9e03cc9cc71ec 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1110,6 +1110,10 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere Self::to_string(|s| s.print_visibility(v)) } + fn impl_restriction_to_string(&self, r: &ast::ImplRestriction) -> String { + Self::to_string(|s| s.print_impl_restriction(r)) + } + fn block_to_string(&self, blk: &ast::Block) -> String { Self::to_string(|s| { let (cb, ib) = s.head(""); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 57e105010343c..3407feb3dcc3a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -365,6 +365,7 @@ impl<'a> State<'a> { constness, safety, is_auto, + impl_restriction, ident, generics, bounds, @@ -375,6 +376,7 @@ impl<'a> State<'a> { self.print_constness(*constness); self.print_safety(*safety); self.print_is_auto(*is_auto); + self.print_impl_restriction(impl_restriction); self.word_nbsp("trait"); self.print_ident(*ident); self.print_generic_params(&generics.params); @@ -483,6 +485,20 @@ impl<'a> State<'a> { } } + pub(crate) fn print_impl_restriction(&mut self, impl_restriction: &ast::ImplRestriction) { + match &impl_restriction.kind { + ast::RestrictionKind::Restricted { path, shorthand, .. } => { + let path = Self::to_string(|s| s.print_path(path, false, 0)); + if *shorthand { + self.word_nbsp(format!("impl({path})")) + } else { + self.word_nbsp(format!("impl(in {path})")) + } + } + ast::RestrictionKind::Unrestricted => {} + } + } + fn print_defaultness(&mut self, defaultness: ast::Defaultness) { if let ast::Defaultness::Default(_) = defaultness { self.word_nbsp("default"); From 2a48c197c46fbc991229595ab438f095a65ce151 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:28:12 +0900 Subject: [PATCH 25/35] Discard `impl` restrictions during HIR lowering for now --- compiler/rustc_ast_lowering/src/item.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d56a75097acd4..67ec8c7611761 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -512,6 +512,8 @@ impl<'hir> LoweringContext<'_, 'hir> { constness, is_auto, safety, + // FIXME(impl_restrictions): lower to HIR + impl_restriction: _, ident, generics, bounds, From 9bf249415d60aa2d1dad44e2175e7ab0c146c090 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:31:24 +0900 Subject: [PATCH 26/35] Add `eq_impl_restriction` to clippy_utils --- .../clippy/clippy_utils/src/ast_utils/mod.rs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 67ae1dcef81be..50cfb0ed89dec 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -449,6 +449,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { constness: lc, is_auto: la, safety: lu, + impl_restriction: liprt, ident: li, generics: lg, bounds: lb, @@ -458,6 +459,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { constness: rc, is_auto: ra, safety: ru, + impl_restriction: riprt, ident: ri, generics: rg, bounds: rb, @@ -467,6 +469,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No) && la == ra && matches!(lu, Safety::Default) == matches!(ru, Safety::Default) + && eq_impl_restriction(liprt, riprt) && eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound) @@ -834,6 +837,29 @@ pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool { } } +pub fn eq_impl_restriction(l: &ImplRestriction, r: &ImplRestriction) -> bool { + eq_restriction_kind(&l.kind, &r.kind) +} + +fn eq_restriction_kind(l: &RestrictionKind, r: &RestrictionKind) -> bool { + match (l, r) { + (RestrictionKind::Unrestricted, RestrictionKind::Unrestricted) => true, + ( + RestrictionKind::Restricted { + path: l_path, + shorthand: l_short, + id: _, + }, + RestrictionKind::Restricted { + path: r_path, + shorthand: r_short, + id: _, + }, + ) => l_short == r_short && eq_path(l_path, r_path), + _ => false, + } +} + pub fn eq_fn_decl(l: &FnDecl, r: &FnDecl) -> bool { eq_fn_ret_ty(&l.output, &r.output) && over(&l.inputs, &r.inputs, |l, r| { From f40881d1e505ee4ab55dcb7b083af63366863147 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:33:48 +0900 Subject: [PATCH 27/35] rustfmt `impl` restriction --- src/tools/rustfmt/src/items.rs | 4 +- src/tools/rustfmt/src/utils.rs | 38 ++++++++++++++++- .../rustfmt/tests/source/impl-restriction.rs | 41 +++++++++++++++++++ .../rustfmt/tests/target/impl-restriction.rs | 15 +++++++ 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 src/tools/rustfmt/tests/source/impl-restriction.rs create mode 100644 src/tools/rustfmt/tests/target/impl-restriction.rs diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 2c5fcf09c9f16..a4251a9a3bd4e 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -1158,6 +1158,7 @@ pub(crate) fn format_trait( constness, is_auto, safety, + ref impl_restriction, ident, ref generics, ref bounds, @@ -1166,11 +1167,12 @@ pub(crate) fn format_trait( let mut result = String::with_capacity(128); let header = format!( - "{}{}{}{}trait ", + "{}{}{}{}{}trait ", format_visibility(context, &item.vis), format_constness(constness), format_safety(safety), format_auto(is_auto), + format_impl_restriction(context, impl_restriction), ); result.push_str(&header); diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index b676803379f7c..b052e74d8bf20 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -2,8 +2,8 @@ use std::borrow::Cow; use rustc_ast::YieldKind; use rustc_ast::ast::{ - self, Attribute, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, Visibility, - VisibilityKind, + self, Attribute, ImplRestriction, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, + RestrictionKind, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol}; @@ -74,6 +74,40 @@ pub(crate) fn format_visibility( } } +pub(crate) fn format_impl_restriction( + context: &RewriteContext<'_>, + impl_restriction: &ImplRestriction, +) -> String { + format_restriction("impl", context, &impl_restriction.kind) +} + +fn format_restriction( + kw: &'static str, + context: &RewriteContext<'_>, + restriction: &RestrictionKind, +) -> String { + match restriction { + RestrictionKind::Unrestricted => String::new(), + RestrictionKind::Restricted { + ref path, + id: _, + shorthand, + } => { + let Path { ref segments, .. } = **path; + let mut segments_iter = segments.iter().map(|seg| rewrite_ident(context, seg.ident)); + if path.is_global() && segments_iter.next().is_none() { + panic!("non-global path in {kw}(restricted)?"); + } + // FIXME use `segments_iter.intersperse("::").collect::()` once + // `#![feature(iter_intersperse)]` is re-stabilized. + let path = itertools::join(segments_iter, "::"); + let in_str = if *shorthand { "" } else { "in " }; + + format!("{kw}({in_str}{path}) ") + } + } +} + #[inline] pub(crate) fn format_coro(coroutine_kind: &ast::CoroutineKind) -> &'static str { match coroutine_kind { diff --git a/src/tools/rustfmt/tests/source/impl-restriction.rs b/src/tools/rustfmt/tests/source/impl-restriction.rs new file mode 100644 index 0000000000000..4459d9a8ba2b5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/impl-restriction.rs @@ -0,0 +1,41 @@ +#![feature(impl_restriction)] + +pub +impl(crate) +trait Foo {} + +pub impl +( in +crate ) +trait +Bar +{} + +pub +impl ( in foo +:: +bar ) +trait Baz {} + +pub +const +impl +(self) +trait QuxConst {} + +pub +auto impl( +super +) +trait QuxAuto {} + +pub +unsafe impl +(in crate) +trait QuxUnsafe {} + +pub const +unsafe impl +(in super +::foo) +trait QuxConstUnsafe {} diff --git a/src/tools/rustfmt/tests/target/impl-restriction.rs b/src/tools/rustfmt/tests/target/impl-restriction.rs new file mode 100644 index 0000000000000..4ff617af0f257 --- /dev/null +++ b/src/tools/rustfmt/tests/target/impl-restriction.rs @@ -0,0 +1,15 @@ +#![feature(impl_restriction)] + +pub impl(crate) trait Foo {} + +pub impl(in crate) trait Bar {} + +pub impl(in foo::bar) trait Baz {} + +pub const impl(self) trait QuxConst {} + +pub auto impl(super) trait QuxAuto {} + +pub unsafe impl(in crate) trait QuxUnsafe {} + +pub const unsafe impl(in super::foo) trait QuxConstUnsafe {} From 26d4291ed4e16827c51f10d10046e5eb7dd1f17a Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:34:43 +0900 Subject: [PATCH 28/35] Add ui tests --- tests/ui/README.md | 5 + .../feature-gate-impl-restriction.rs | 43 +++++ ...-gate-impl-restriction.without_gate.stderr | 173 ++++++++++++++++++ .../recover-incorrect-impl-restriction.rs | 20 ++ ...ncorrect-impl-restriction.with_gate.stderr | 107 +++++++++++ ...rrect-impl-restriction.without_gate.stderr | 159 ++++++++++++++++ tests/ui/macros/stringify.rs | 105 +++++++++++ 7 files changed, 612 insertions(+) create mode 100644 tests/ui/impl-restriction/feature-gate-impl-restriction.rs create mode 100644 tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr create mode 100644 tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs create mode 100644 tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr create mode 100644 tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr diff --git a/tests/ui/README.md b/tests/ui/README.md index d2b189a0e022c..a24cb761c6790 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -699,6 +699,11 @@ This test category revolves around trait objects with `Sized` having illegal ope Tests on lifetime elision in impl function signatures. See [Lifetime elision | Nomicon](https://doc.rust-lang.org/nomicon/lifetime-elision.html). +## `tests/ui/impl-restriction/` +Tests for `#![feature(impl_restriction)]`. See [Tracking issue for restrictions #105077 +](https://github.com/rust-lang/rust/issues/105077). + + ## `tests/ui/impl-trait/` Tests for trait impls. diff --git a/tests/ui/impl-restriction/feature-gate-impl-restriction.rs b/tests/ui/impl-restriction/feature-gate-impl-restriction.rs new file mode 100644 index 0000000000000..95a050fe444ab --- /dev/null +++ b/tests/ui/impl-restriction/feature-gate-impl-restriction.rs @@ -0,0 +1,43 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +//@[with_gate] check-pass + +#![cfg_attr(with_gate, feature(impl_restriction))] +#![cfg_attr(with_gate, allow(incomplete_features))] +#![feature(auto_traits, const_trait_impl)] + +pub impl(crate) trait Bar {} //[without_gate]~ ERROR `impl` restrictions are experimental +pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictions are experimental + +mod foo { + pub impl(in crate::foo) trait Baz {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub unsafe impl(super) trait BazUnsafeSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub auto impl(self) trait BazAutoSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub const impl(in self) trait BazConst {} //[without_gate]~ ERROR `impl` restrictions are experimental + + mod foo_inner { + pub impl(in crate::foo::foo_inner) trait Qux {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + } + + #[cfg(false)] + pub impl(crate) trait Bar {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub unsafe impl(self) trait BazUnsafeSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub auto impl(in super) trait BazAutoSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub const impl(super) trait BazConstSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + + #[cfg(false)] + mod cfged_out_foo { + pub impl(in crate::foo::cfged_out_foo) trait CfgedOutQux {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + } + + // auto traits cannot be const, so we do not include these combinations in the test. +} diff --git a/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr new file mode 100644 index 0000000000000..4f99d962d4bb7 --- /dev/null +++ b/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr @@ -0,0 +1,173 @@ +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:9:5 + | +LL | pub impl(crate) trait Bar {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:10:5 + | +LL | pub impl(in crate) trait BarInCrate {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:13:9 + | +LL | pub impl(in crate::foo) trait Baz {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:14:16 + | +LL | pub unsafe impl(super) trait BazUnsafeSuper {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:15:14 + | +LL | pub auto impl(self) trait BazAutoSelf {} + | ^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:16:15 + | +LL | pub const impl(in self) trait BazConst {} + | ^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:19:13 + | +LL | pub impl(in crate::foo::foo_inner) trait Qux {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:20:25 + | +LL | ... pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:21:26 + | +LL | ... pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:25:9 + | +LL | pub impl(crate) trait Bar {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:27:9 + | +LL | pub impl(in crate) trait BarInCrate {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:29:16 + | +LL | pub unsafe impl(self) trait BazUnsafeSelf {} + | ^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:31:14 + | +LL | pub auto impl(in super) trait BazAutoSuper {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:33:15 + | +LL | pub const impl(super) trait BazConstSuper {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:37:13 + | +LL | pub impl(in crate::foo::cfged_out_foo) trait CfgedOutQux {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:38:25 + | +LL | ... pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:39:26 + | +LL | ... pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 17 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs new file mode 100644 index 0000000000000..d6490d5b4f978 --- /dev/null +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs @@ -0,0 +1,20 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +#![cfg_attr(with_gate, feature(impl_restriction))] +//[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes +#![feature(auto_traits, const_trait_impl)] + +mod foo { + pub impl(crate::foo) trait Baz {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub unsafe impl(crate::foo) trait BazUnsafe {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub auto impl(crate::foo) trait BazAuto {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub const impl(crate::foo) trait BazConst {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub const unsafe impl(crate::foo) trait BazConstUnsafe {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental +} diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr new file mode 100644 index 0000000000000..ad183b23e0138 --- /dev/null +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr @@ -0,0 +1,107 @@ +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + | +LL | pub impl(crate::foo) trait Baz {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub impl(in crate::foo) trait Baz {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + | +LL | pub unsafe impl(crate::foo) trait BazUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + | +LL | pub auto impl(crate::foo) trait BazAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub auto impl(in crate::foo) trait BazAuto {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + | +LL | pub const impl(crate::foo) trait BazConst {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const impl(in crate::foo) trait BazConst {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + | +LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + | +LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} + | ++ + +warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/recover-incorrect-impl-restriction.rs:3:32 + | +LL | #![cfg_attr(with_gate, feature(impl_restriction))] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 6 previous errors; 1 warning emitted + diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr new file mode 100644 index 0000000000000..d949172ffb458 --- /dev/null +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr @@ -0,0 +1,159 @@ +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + | +LL | pub impl(crate::foo) trait Baz {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub impl(in crate::foo) trait Baz {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + | +LL | pub unsafe impl(crate::foo) trait BazUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + | +LL | pub auto impl(crate::foo) trait BazAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub auto impl(in crate::foo) trait BazAuto {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + | +LL | pub const impl(crate::foo) trait BazConst {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const impl(in crate::foo) trait BazConst {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + | +LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + | +LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} + | ++ + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:8:9 + | +LL | pub impl(crate::foo) trait Baz {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:10:16 + | +LL | pub unsafe impl(crate::foo) trait BazUnsafe {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:12:14 + | +LL | pub auto impl(crate::foo) trait BazAuto {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:14:15 + | +LL | pub const impl(crate::foo) trait BazConst {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:16:22 + | +LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:18:21 + | +LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 890b429b4ac7d..f4f66745372b5 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -800,6 +800,111 @@ macro_rules! p { }; } +#[test] +fn test_impl_restriction() { + assert_eq!( + stringify!(pub impl(crate) trait Foo {}), + "pub impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in crate) trait Foo {}), + "pub impl(in crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(super) trait Foo {}), + "pub impl(super) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in super) trait Foo {}), + "pub impl(in super) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(self) trait Foo {}), + "pub impl(self) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in self) trait Foo {}), + "pub impl(in self) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in path::to) trait Foo {}), + "pub impl(in path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in ::path::to) trait Foo {}), + "pub impl(in ::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in self::path::to) trait Foo {}), + "pub impl(in self::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in super::path::to) trait Foo {}), + "pub impl(in super::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in crate::path::to) trait Foo {}), + "pub impl(in crate::path::to) trait Foo {}" + ); + + assert_eq!( + stringify!(pub auto impl(crate) trait Foo {}), + "pub auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub auto impl(in crate::path::to) trait Foo {}), + "pub auto impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe impl(crate) trait Foo {}), + "pub unsafe impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe impl(in crate::path::to) trait Foo {}), + "pub unsafe impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const impl(crate) trait Foo {}), + "pub const impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const impl(in crate::path::to) trait Foo {}), + "pub const impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe auto impl(crate) trait Foo {}), + "pub unsafe auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe auto impl(in crate::path::to) trait Foo {}), + "pub unsafe auto impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const auto impl(crate) trait Foo {}), + "pub const auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const auto impl(in crate::path::to) trait Foo {}), + "pub const auto impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe impl(crate) trait Foo {}), + "pub const unsafe impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe impl(in crate::path::to) trait Foo {}), + "pub const unsafe impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe auto impl(crate) trait Foo {}), + "pub const unsafe auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe auto impl(in crate::path::to) trait Foo {}), + "pub const unsafe auto impl(in crate::path::to) trait Foo {}" + ); +} + #[test] fn test_punct() { // For all these cases, we should preserve spaces between the tokens. From 3dcefa371d82c43c9a98212aa86b68fa214e8fbd Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Mon, 23 Feb 2026 14:12:19 +0900 Subject: [PATCH 29/35] Trait aliases cannot be `impl`-restricted --- compiler/rustc_parse/src/errors.rs | 8 + compiler/rustc_parse/src/parser/item.rs | 3 + .../trait-alias-cannot-be-impl-restricted.rs | 28 ++++ ...cannot-be-impl-restricted.with_gate.stderr | 83 ++++++++++ ...not-be-impl-restricted.without_gate.stderr | 145 ++++++++++++++++++ 5 files changed, 267 insertions(+) create mode 100644 tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs create mode 100644 tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr create mode 100644 tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 15e7fe805845a..4b648b3464a89 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2422,6 +2422,14 @@ pub(crate) struct TraitAliasCannotBeUnsafe { pub span: Span, } +#[derive(Diagnostic)] +#[diag("trait aliases cannot be `impl`-restricted")] +pub(crate) struct TraitAliasCannotBeImplRestricted { + #[primary_span] + #[label("trait aliases cannot be `impl`-restricted")] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("associated `static` items are not allowed")] pub(crate) struct AssociatedStaticItemNotAllowed { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index c3b8aac220a80..db5be5feaeb6e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1142,6 +1142,9 @@ impl<'a> Parser<'a> { if let Safety::Unsafe(_) = safety { self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span }); } + if let RestrictionKind::Restricted { .. } = impl_restriction.kind { + self.dcx().emit_err(errors::TraitAliasCannotBeImplRestricted { span: whole_span }); + } self.psess.gated_spans.gate(sym::trait_alias, whole_span); diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs new file mode 100644 index 0000000000000..62622e1d55861 --- /dev/null +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs @@ -0,0 +1,28 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +#![cfg_attr(with_gate, feature(impl_restriction))] +//[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes +#![feature(auto_traits, const_trait_impl, trait_alias)] + +impl(crate) trait Alias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//[without_gate]~^ ERROR `impl` restrictions are experimental +auto impl(in crate) trait AutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//~^ ERROR trait aliases cannot be `auto` +//[without_gate]~| ERROR `impl` restrictions are experimental +unsafe impl(self) trait UnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//~^ ERROR trait aliases cannot be `unsafe` +//[without_gate]~| ERROR `impl` restrictions are experimental +const impl(in self) trait ConstAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//[without_gate]~^ ERROR `impl` restrictions are experimental + +mod foo { + impl(super) trait InnerAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + //[without_gate]~^ ERROR `impl` restrictions are experimental + const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + //~^ ERROR trait aliases cannot be `unsafe` + //[without_gate]~| ERROR `impl` restrictions are experimental + unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + //~^ ERROR trait aliases cannot be `auto` + //~^^ ERROR trait aliases cannot be `unsafe` + //[without_gate]~| ERROR `impl` restrictions are experimental +} diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr new file mode 100644 index 0000000000000..70287aca42aad --- /dev/null +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr @@ -0,0 +1,83 @@ +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + | +LL | impl(crate) trait Alias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + | +LL | const impl(in self) trait ConstAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + | +LL | impl(super) trait InnerAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:3:32 + | +LL | #![cfg_attr(with_gate, feature(impl_restriction))] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 12 previous errors; 1 warning emitted + diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr new file mode 100644 index 0000000000000..7bff90396708d --- /dev/null +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr @@ -0,0 +1,145 @@ +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + | +LL | impl(crate) trait Alias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + | +LL | const impl(in self) trait ConstAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + | +LL | impl(super) trait InnerAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + | +LL | impl(crate) trait Alias = Copy; + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:6 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:8 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:7 + | +LL | const impl(in self) trait ConstAlias = Copy; + | ^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + | +LL | impl(super) trait InnerAlias = Copy; + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:18 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:17 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0658`. From 7b34c00e80414a155928e3665d85905f41f3a8ff Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 27 Feb 2026 14:37:32 +0000 Subject: [PATCH 30/35] Fix typo in test name --- tests/ui/rmeta/{no_optitimized_mir.rs => no_optimized_mir.rs} | 0 .../rmeta/{no_optitimized_mir.stderr => no_optimized_mir.stderr} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/rmeta/{no_optitimized_mir.rs => no_optimized_mir.rs} (100%) rename tests/ui/rmeta/{no_optitimized_mir.stderr => no_optimized_mir.stderr} (100%) diff --git a/tests/ui/rmeta/no_optitimized_mir.rs b/tests/ui/rmeta/no_optimized_mir.rs similarity index 100% rename from tests/ui/rmeta/no_optitimized_mir.rs rename to tests/ui/rmeta/no_optimized_mir.rs diff --git a/tests/ui/rmeta/no_optitimized_mir.stderr b/tests/ui/rmeta/no_optimized_mir.stderr similarity index 100% rename from tests/ui/rmeta/no_optitimized_mir.stderr rename to tests/ui/rmeta/no_optimized_mir.stderr From a192c617ecfbe15f6feab06d5756a4cab835b8c8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 27 Feb 2026 14:33:23 +0000 Subject: [PATCH 31/35] Use CompiledModules inside CodegenResults In preparation for fully replacing CodegenResults with CompiledModules. --- .../rustc_codegen_cranelift/src/driver/aot.rs | 14 +- compiler/rustc_codegen_llvm/src/lib.rs | 10 +- compiler/rustc_codegen_ssa/src/back/link.rs | 308 +++++++++--------- compiler/rustc_codegen_ssa/src/back/write.rs | 32 +- compiler/rustc_codegen_ssa/src/lib.rs | 7 +- .../rustc_codegen_ssa/src/traits/backend.rs | 8 +- compiler/rustc_driver_impl/src/lib.rs | 8 +- compiler/rustc_interface/src/passes.rs | 5 +- compiler/rustc_interface/src/queries.rs | 8 +- compiler/rustc_interface/src/util.rs | 18 +- .../codegen-backend/auxiliary/the_backend.rs | 10 +- 11 files changed, 209 insertions(+), 219 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index fc5c634d95709..7a736de967d21 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -10,9 +10,9 @@ use std::thread::JoinHandle; use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; -use rustc_codegen_ssa::back::write::{CompiledModules, produce_final_output_artifacts}; +use rustc_codegen_ssa::back::write::produce_final_output_artifacts; use rustc_codegen_ssa::base::determine_cgu_reuse; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; +use rustc_codegen_ssa::{CodegenResults, CompiledModule, CompiledModules, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; @@ -126,15 +126,7 @@ impl OngoingCodegen { produce_final_output_artifacts(sess, &compiled_modules, outputs); - ( - CodegenResults { - crate_info: self.crate_info, - - modules: compiled_modules.modules, - allocator_module: compiled_modules.allocator_module, - }, - work_products, - ) + (CodegenResults { compiled_modules, crate_info: self.crate_info }, work_products) } } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 7120ee0afec96..5282b723c2b90 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -33,7 +33,9 @@ use rustc_codegen_ssa::back::write::{ TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; +use rustc_codegen_ssa::{ + CodegenResults, CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig, +}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; @@ -392,7 +394,8 @@ impl CodegenBackend for LlvmCodegenBackend { fn link( &self, sess: &Session, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, ) { @@ -405,7 +408,8 @@ impl CodegenBackend for LlvmCodegenBackend { link_binary( sess, &LlvmArchiveBuilderBuilder, - codegen_results, + compiled_modules, + crate_info, metadata, outputs, self.name(), diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 388503c720532..11bee7f865f6c 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -60,7 +60,7 @@ use super::rpath::{self, RPathConfig}; use super::{apple, versioned_llvm_target}; use crate::base::needs_allocator_shim_for_linking; use crate::{ - CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file, + CompiledModule, CompiledModules, CrateInfo, NativeLib, errors, looks_like_rust_object_file, }; pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { @@ -76,7 +76,8 @@ pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { pub fn link_binary( sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, codegen_backend: &'static str, @@ -84,7 +85,7 @@ pub fn link_binary( let _timer = sess.timer("link_binary"); let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); let mut tempfiles_for_stdout_output: Vec = Vec::new(); - for &crate_type in &codegen_results.crate_info.crate_types { + for &crate_type in &crate_info.crate_types { // Ignore executable crates if we have -Z no-codegen, as they will error. if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen()) && !output_metadata @@ -98,25 +99,20 @@ pub fn link_binary( } sess.time("link_binary_check_files_are_writeable", || { - for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { + for obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) { check_file_is_writeable(obj, sess); } }); if outputs.outputs.should_link() { - let output = out_filename( - sess, - crate_type, - outputs, - codegen_results.crate_info.local_crate_name, - ); + let output = out_filename(sess, crate_type, outputs, crate_info.local_crate_name); let tmpdir = TempDirBuilder::new() .prefix("rustc") .tempdir_in(output.parent().unwrap_or_else(|| Path::new("."))) .unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error })); let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); - let crate_name = format!("{}", codegen_results.crate_info.local_crate_name); + let crate_name = format!("{}", crate_info.local_crate_name); let out_filename = output.file_for_writing( outputs, OutputType::Exe, @@ -130,7 +126,8 @@ pub fn link_binary( link_rlib( sess, archive_builder_builder, - &codegen_results, + &compiled_modules, + &crate_info, &metadata, RlibFlavor::Normal, &path, @@ -141,7 +138,8 @@ pub fn link_binary( link_staticlib( sess, archive_builder_builder, - &codegen_results, + &compiled_modules, + &crate_info, &metadata, &out_filename, &path, @@ -153,7 +151,8 @@ pub fn link_binary( archive_builder_builder, crate_type, &out_filename, - &codegen_results, + &compiled_modules, + &crate_info, &metadata, path.as_ref(), codegen_backend, @@ -218,7 +217,7 @@ pub fn link_binary( |module: &CompiledModule| maybe_remove_temps_from_module(false, false, module); // Otherwise, always remove the allocator module temporaries. - if let Some(ref allocator_module) = codegen_results.allocator_module { + if let Some(ref allocator_module) = compiled_modules.allocator_module { remove_temps_from_module(allocator_module); } @@ -237,7 +236,7 @@ pub fn link_binary( let (preserve_objects, preserve_dwarf_objects) = preserve_objects_for_their_debuginfo(sess); debug!(?preserve_objects, ?preserve_dwarf_objects); - for module in &codegen_results.modules { + for module in &compiled_modules.modules { maybe_remove_temps_from_module(preserve_objects, preserve_dwarf_objects, module); } }); @@ -298,7 +297,8 @@ pub fn each_linked_rlib( fn link_rlib<'a>( sess: &'a Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, flavor: RlibFlavor, tmpdir: &MaybeTempDir, @@ -327,7 +327,7 @@ fn link_rlib<'a>( RlibFlavor::StaticlibBase => None, }; - for m in &codegen_results.modules { + for m in &compiled_modules.modules { if let Some(obj) = m.object.as_ref() { ab.add_file(obj); } @@ -340,7 +340,7 @@ fn link_rlib<'a>( match flavor { RlibFlavor::Normal => {} RlibFlavor::StaticlibBase => { - let obj = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref()); + let obj = compiled_modules.allocator_module.as_ref().and_then(|m| m.object.as_ref()); if let Some(obj) = obj { ab.add_file(obj); } @@ -366,7 +366,7 @@ fn link_rlib<'a>( // feature then we'll need to figure out how to record what objects were // loaded from the libraries found here and then encode that into the // metadata of the rlib we're generating somehow. - for lib in codegen_results.crate_info.used_libraries.iter() { + for lib in crate_info.used_libraries.iter() { let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else { continue; }; @@ -394,7 +394,7 @@ fn link_rlib<'a>( for output_path in raw_dylib::create_raw_dylib_dll_import_libs( sess, archive_builder_builder, - codegen_results.crate_info.used_libraries.iter(), + crate_info.used_libraries.iter(), tmpdir.as_ref(), true, ) { @@ -457,7 +457,8 @@ fn link_rlib<'a>( fn link_staticlib( sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, out_filename: &Path, tempdir: &MaybeTempDir, @@ -466,72 +467,67 @@ fn link_staticlib( let mut ab = link_rlib( sess, archive_builder_builder, - codegen_results, + compiled_modules, + crate_info, metadata, RlibFlavor::StaticlibBase, tempdir, ); let mut all_native_libs = vec![]; - let res = each_linked_rlib( - &codegen_results.crate_info, - Some(CrateType::StaticLib), - &mut |cnum, path| { - let lto = are_upstream_rust_objects_already_included(sess) - && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); - - let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter(); - let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib)); - let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect(); - - let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); - ab.add_archive( - path, - Box::new(move |fname: &str| { - // Ignore metadata files, no matter the name. - if fname == METADATA_FILENAME { - return true; - } + let res = each_linked_rlib(crate_info, Some(CrateType::StaticLib), &mut |cnum, path| { + let lto = are_upstream_rust_objects_already_included(sess) + && !ignored_for_lto(sess, crate_info, cnum); - // Don't include Rust objects if LTO is enabled - if lto && looks_like_rust_object_file(fname) { - return true; - } + let native_libs = crate_info.native_libraries[&cnum].iter(); + let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib)); + let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect(); - // Skip objects for bundled libs. - if bundled_libs.contains(&Symbol::intern(fname)) { - return true; - } + let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); + ab.add_archive( + path, + Box::new(move |fname: &str| { + // Ignore metadata files, no matter the name. + if fname == METADATA_FILENAME { + return true; + } - false - }), - ) - .unwrap(); + // Don't include Rust objects if LTO is enabled + if lto && looks_like_rust_object_file(fname) { + return true; + } - archive_builder_builder - .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs) - .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); + // Skip objects for bundled libs. + if bundled_libs.contains(&Symbol::intern(fname)) { + return true; + } - for filename in relevant_libs.iter() { - let joined = tempdir.as_ref().join(filename.as_str()); - let path = joined.as_path(); - ab.add_archive(path, Box::new(|_| false)).unwrap(); - } + false + }), + ) + .unwrap(); - all_native_libs - .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); - }, - ); + archive_builder_builder + .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs) + .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); + + for filename in relevant_libs.iter() { + let joined = tempdir.as_ref().join(filename.as_str()); + let path = joined.as_path(); + ab.add_archive(path, Box::new(|_| false)).unwrap(); + } + + all_native_libs.extend(crate_info.native_libraries[&cnum].iter().cloned()); + }); if let Err(e) = res { sess.dcx().emit_fatal(e); } ab.build(out_filename); - let crates = codegen_results.crate_info.used_crates.iter(); + let crates = crate_info.used_crates.iter(); - let fmts = codegen_results - .crate_info + let fmts = crate_info .dependency_formats .get(&CrateType::StaticLib) .expect("no dependency formats for staticlib"); @@ -541,8 +537,8 @@ fn link_staticlib( let Some(Linkage::Dynamic) = fmts.get(cnum) else { continue; }; - let crate_name = codegen_results.crate_info.crate_name[&cnum]; - let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; + let crate_name = crate_info.crate_name[&cnum]; + let used_crate_source = &crate_info.used_crate_source[&cnum]; if let Some(path) = &used_crate_source.dylib { all_rust_dylibs.push(&**path); } else if used_crate_source.rmeta.is_some() { @@ -552,7 +548,7 @@ fn link_staticlib( } } - all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries); + all_native_libs.extend_from_slice(&crate_info.used_libraries); for print in &sess.opts.prints { if print.kind == PrintKind::NativeStaticLibs { @@ -563,7 +559,12 @@ fn link_staticlib( /// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a /// DWARF package. -fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out_filename: &Path) { +fn link_dwarf_object( + sess: &Session, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, + executable_out_filename: &Path, +) { let mut dwp_out_filename = executable_out_filename.to_path_buf().into_os_string(); dwp_out_filename.push(".dwp"); debug!(?dwp_out_filename, ?executable_out_filename); @@ -604,20 +605,21 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out // Input objs contain .o/.dwo files from the current crate. match sess.opts.unstable_opts.split_dwarf_kind { SplitDwarfKind::Single => { - for input_obj in cg_results.modules.iter().filter_map(|m| m.object.as_ref()) { + for input_obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) { package.add_input_object(input_obj)?; } } SplitDwarfKind::Split => { - for input_obj in cg_results.modules.iter().filter_map(|m| m.dwarf_object.as_ref()) { + for input_obj in + compiled_modules.modules.iter().filter_map(|m| m.dwarf_object.as_ref()) + { package.add_input_object(input_obj)?; } } } // Input rlibs contain .o/.dwo files from dependencies. - let input_rlibs = cg_results - .crate_info + let input_rlibs = crate_info .used_crate_source .items() .filter_map(|(_, csource)| csource.rlib.as_ref()) @@ -679,7 +681,8 @@ fn link_natively( archive_builder_builder: &dyn ArchiveBuilderBuilder, crate_type: CrateType, out_filename: &Path, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, tmpdir: &Path, codegen_backend: &'static str, @@ -705,7 +708,8 @@ fn link_natively( crate_type, tmpdir, temp_filename, - codegen_results, + compiled_modules, + crate_info, metadata, self_contained_components, codegen_backend, @@ -936,7 +940,7 @@ fn link_natively( } } - let level = codegen_results.crate_info.lint_levels.linker_messages; + let level = crate_info.lint_levels.linker_messages; let lint = |msg| { diag_lint_level(sess, LINKER_MESSAGES, level, None, LinkerOutput { inner: msg }); }; @@ -1013,7 +1017,9 @@ fn link_natively( // We cannot rely on the .o paths in the executable because they may have been // remapped by --remap-path-prefix and therefore invalid, so we need to provide // the .o/.dwo paths explicitly. - SplitDebuginfo::Packed => link_dwarf_object(sess, codegen_results, out_filename), + SplitDebuginfo::Packed => { + link_dwarf_object(sess, compiled_modules, crate_info, out_filename) + } } let strip = sess.opts.cg.strip; @@ -1908,11 +1914,11 @@ fn add_late_link_args( sess: &Session, flavor: LinkerFlavor, crate_type: CrateType, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, ) { let any_dynamic_crate = crate_type == CrateType::Dylib || crate_type == CrateType::Sdylib - || codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| { + || crate_info.dependency_formats.iter().any(|(ty, list)| { *ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic) }); if any_dynamic_crate { @@ -2074,8 +2080,8 @@ fn add_linked_symbol_object( } /// Add object files containing code from the current crate. -fn add_local_crate_regular_objects(cmd: &mut dyn Linker, codegen_results: &CodegenResults) { - for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { +fn add_local_crate_regular_objects(cmd: &mut dyn Linker, compiled_modules: &CompiledModules) { + for obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) { cmd.add_object(obj); } } @@ -2083,12 +2089,13 @@ fn add_local_crate_regular_objects(cmd: &mut dyn Linker, codegen_results: &Codeg /// Add object files for allocator code linked once for the whole crate tree. fn add_local_crate_allocator_objects( cmd: &mut dyn Linker, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, crate_type: CrateType, ) { - if needs_allocator_shim_for_linking(&codegen_results.crate_info.dependency_formats, crate_type) - { - if let Some(obj) = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref()) + if needs_allocator_shim_for_linking(&crate_info.dependency_formats, crate_type) { + if let Some(obj) = + compiled_modules.allocator_module.as_ref().and_then(|m| m.object.as_ref()) { cmd.add_object(obj); } @@ -2102,7 +2109,7 @@ fn add_local_crate_metadata_objects( archive_builder_builder: &dyn ArchiveBuilderBuilder, crate_type: CrateType, tmpdir: &Path, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, metadata: &EncodedMetadata, ) { // When linking a dynamic library, we put the metadata into a section of the @@ -2112,7 +2119,7 @@ fn add_local_crate_metadata_objects( let data = archive_builder_builder.create_dylib_metadata_wrapper( sess, &metadata, - &codegen_results.crate_info.metadata_symbol, + &crate_info.metadata_symbol, ); let obj = emit_wrapper_file(sess, &data, tmpdir, "rmeta.o"); @@ -2157,7 +2164,7 @@ fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) { fn add_rpath_args( cmd: &mut dyn Linker, sess: &Session, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, out_filename: &Path, ) { if !sess.target.has_rpath { @@ -2168,11 +2175,10 @@ fn add_rpath_args( // where extern libraries might live, based on the // add_lib_search_paths if sess.opts.cg.rpath { - let libs = codegen_results - .crate_info + let libs = crate_info .used_crates .iter() - .filter_map(|cnum| codegen_results.crate_info.used_crate_source[cnum].dylib.as_deref()) + .filter_map(|cnum| crate_info.used_crate_source[cnum].dylib.as_deref()) .collect::>(); let rpath_config = RPathConfig { libs: &*libs, @@ -2265,7 +2271,8 @@ fn linker_with_args( crate_type: CrateType, tmpdir: &Path, out_filename: &Path, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, self_contained_components: LinkSelfContainedComponents, codegen_backend: &'static str, @@ -2276,17 +2283,17 @@ fn linker_with_args( path, flavor, self_contained_components.are_any_components_enabled(), - &codegen_results.crate_info.target_cpu, + &crate_info.target_cpu, codegen_backend, ); let link_output_kind = link_output_kind(sess, crate_type); - let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone(); + let mut export_symbols = crate_info.exported_symbols[&crate_type].clone(); if crate_type == CrateType::Cdylib { let mut seen = FxHashSet::default(); - for lib in &codegen_results.crate_info.used_libraries { + for lib in &crate_info.used_libraries { if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind && seen.insert((lib.name, lib.verbatim)) { @@ -2320,12 +2327,7 @@ fn linker_with_args( // Pre-link CRT objects. add_pre_link_objects(cmd, sess, flavor, link_output_kind, self_contained_crt_objects); - add_linked_symbol_object( - cmd, - sess, - tmpdir, - &codegen_results.crate_info.linked_symbols[&crate_type], - ); + add_linked_symbol_object(cmd, sess, tmpdir, &crate_info.linked_symbols[&crate_type]); // Sanitizer libraries. add_sanitizer_libraries(sess, flavor, crate_type, cmd); @@ -2357,17 +2359,17 @@ fn linker_with_args( // link line. And finally upstream native libraries can't depend on anything // in this DAG so far because they can only depend on other native libraries // and such dependencies are also required to be specified. - add_local_crate_regular_objects(cmd, codegen_results); + add_local_crate_regular_objects(cmd, compiled_modules); add_local_crate_metadata_objects( cmd, sess, archive_builder_builder, crate_type, tmpdir, - codegen_results, + crate_info, metadata, ); - add_local_crate_allocator_objects(cmd, codegen_results, crate_type); + add_local_crate_allocator_objects(cmd, compiled_modules, crate_info, crate_type); // Avoid linking to dynamic libraries unless they satisfy some undefined symbols // at the point at which they are specified on the command line. @@ -2384,7 +2386,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, link_output_kind, ); @@ -2394,7 +2396,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, crate_type, tmpdir, link_output_kind, @@ -2405,7 +2407,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, link_output_kind, ); @@ -2428,7 +2430,7 @@ fn linker_with_args( for output_path in raw_dylib::create_raw_dylib_dll_import_libs( sess, archive_builder_builder, - codegen_results.crate_info.used_libraries.iter(), + crate_info.used_libraries.iter(), tmpdir, true, ) { @@ -2437,7 +2439,7 @@ fn linker_with_args( } else { for (link_path, as_needed) in raw_dylib::create_raw_dylib_elf_stub_shared_objects( sess, - codegen_results.crate_info.used_libraries.iter(), + crate_info.used_libraries.iter(), &raw_dylib_dir, ) { // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects. @@ -2448,16 +2450,14 @@ fn linker_with_args( // they are used within inlined functions or instantiated generic functions. We do this *after* // handling the raw-dylib symbols in the current crate to make sure that those are chosen first // by the linker. - let dependency_linkage = codegen_results - .crate_info + let dependency_linkage = crate_info .dependency_formats .get(&crate_type) .expect("failed to find crate type in dependency format list"); // We sort the libraries below #[allow(rustc::potential_query_instability)] - let mut native_libraries_from_nonstatics = codegen_results - .crate_info + let mut native_libraries_from_nonstatics = crate_info .native_libraries .iter() .filter_map(|(&cnum, libraries)| { @@ -2499,7 +2499,7 @@ fn linker_with_args( // FIXME: Built-in target specs occasionally use this for linking system libraries, // eliminate all such uses by migrating them to `#[link]` attributes in `lib(std,c,unwind)` // and remove the option. - add_late_link_args(cmd, sess, flavor, crate_type, codegen_results); + add_late_link_args(cmd, sess, flavor, crate_type, crate_info); // ------------ Arbitrary order-independent options ------------ @@ -2512,7 +2512,7 @@ fn linker_with_args( self_contained_components, flavor, crate_type, - codegen_results, + crate_info, out_filename, tmpdir, ); @@ -2552,7 +2552,7 @@ fn add_order_independent_options( self_contained_components: LinkSelfContainedComponents, flavor: LinkerFlavor, crate_type: CrateType, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, out_filename: &Path, tmpdir: &Path, ) { @@ -2597,18 +2597,15 @@ fn add_order_independent_options( "--target", &versioned_llvm_target(sess), "--target-cpu", - &codegen_results.crate_info.target_cpu, + &crate_info.target_cpu, ]); - if codegen_results.crate_info.target_features.len() > 0 { - cmd.link_arg(&format!( - "--target-feature={}", - &codegen_results.crate_info.target_features.join(",") - )); + if crate_info.target_features.len() > 0 { + cmd.link_arg(&format!("--target-feature={}", &crate_info.target_features.join(","))); } } else if flavor == LinkerFlavor::Ptx { - cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]); + cmd.link_args(&["--fallback-arch", &crate_info.target_cpu]); } else if flavor == LinkerFlavor::Bpf { - cmd.link_args(&["--cpu", &codegen_results.crate_info.target_cpu]); + cmd.link_args(&["--cpu", &crate_info.target_cpu]); if let Some(feat) = [sess.opts.cg.target_feature.as_str(), &sess.target.options.features] .into_iter() .find(|feat| !feat.is_empty()) @@ -2625,7 +2622,7 @@ fn add_order_independent_options( if crate_type == CrateType::Executable && sess.target.is_like_windows - && let Some(s) = &codegen_results.crate_info.windows_subsystem + && let Some(s) = &crate_info.windows_subsystem { cmd.windows_subsystem(*s); } @@ -2653,8 +2650,8 @@ fn add_order_independent_options( let natvis_visualizers = collect_natvis_visualizers( tmpdir, sess, - &codegen_results.crate_info.local_crate_name, - &codegen_results.crate_info.natvis_debugger_visualizers, + &crate_info.local_crate_name, + &crate_info.natvis_debugger_visualizers, ); // Pass debuginfo, NatVis debugger visualizers and strip flags down to the linker. @@ -2679,7 +2676,7 @@ fn add_order_independent_options( cmd.ehcont_guard(); } - add_rpath_args(cmd, sess, codegen_results, out_filename); + add_rpath_args(cmd, sess, crate_info, out_filename); } // Write the NatVis debugger visualizer files for each crate to the temp directory and gather the file paths. @@ -2713,7 +2710,7 @@ fn add_native_libs_from_crate( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, bundled_libs: &FxIndexSet, cnum: CrateNum, @@ -2730,15 +2727,15 @@ fn add_native_libs_from_crate( if link_static && cnum != LOCAL_CRATE && !bundled_libs.is_empty() { // If rlib contains native libs as archives, unpack them to tmpdir. - let rlib = codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap(); + let rlib = crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap(); archive_builder_builder .extract_bundled_libs(rlib, tmpdir, bundled_libs) .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); } let native_libs = match cnum { - LOCAL_CRATE => &codegen_results.crate_info.used_libraries, - _ => &codegen_results.crate_info.native_libraries[&cnum], + LOCAL_CRATE => &crate_info.used_libraries, + _ => &crate_info.native_libraries[&cnum], }; let mut last = (None, NativeLibKind::Unspecified, false); @@ -2814,7 +2811,7 @@ fn add_local_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, ) { @@ -2825,7 +2822,7 @@ fn add_local_native_libraries( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, &Default::default(), LOCAL_CRATE, @@ -2839,7 +2836,7 @@ fn add_upstream_rust_crates( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, crate_type: CrateType, tmpdir: &Path, link_output_kind: LinkOutputKind, @@ -2851,8 +2848,7 @@ fn add_upstream_rust_crates( // Linking to a rlib involves just passing it to the linker (the linker // will slurp up the object files inside), and linking to a dynamic library // involves just passing the right -l flag. - let data = codegen_results - .crate_info + let data = crate_info .dependency_formats .get(&crate_type) .expect("failed to find crate type in dependency format list"); @@ -2866,7 +2862,7 @@ fn add_upstream_rust_crates( cmd.link_or_cc_arg("-bnoipath"); } - for &cnum in &codegen_results.crate_info.used_crates { + for &cnum in &crate_info.used_crates { // We may not pass all crates through to the linker. Some crates may appear statically in // an existing dylib, meaning we'll pick up all the symbols from the dylib. // We must always link crates `compiler_builtins` and `profiler_builtins` statically. @@ -2875,14 +2871,14 @@ fn add_upstream_rust_crates( let linkage = data[cnum]; let link_static_crate = linkage == Linkage::Static || linkage == Linkage::IncludedFromDylib - && (codegen_results.crate_info.compiler_builtins == Some(cnum) - || codegen_results.crate_info.profiler_runtime == Some(cnum)); + && (crate_info.compiler_builtins == Some(cnum) + || crate_info.profiler_runtime == Some(cnum)); let mut bundled_libs = Default::default(); match linkage { Linkage::Static | Linkage::IncludedFromDylib | Linkage::NotLinked => { if link_static_crate { - bundled_libs = codegen_results.crate_info.native_libraries[&cnum] + bundled_libs = crate_info.native_libraries[&cnum] .iter() .filter_map(|lib| lib.filename) .collect(); @@ -2890,7 +2886,7 @@ fn add_upstream_rust_crates( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, cnum, &bundled_libs, @@ -2898,7 +2894,7 @@ fn add_upstream_rust_crates( } } Linkage::Dynamic => { - let src = &codegen_results.crate_info.used_crate_source[&cnum]; + let src = &crate_info.used_crate_source[&cnum]; add_dynamic_crate(cmd, sess, src.dylib.as_ref().unwrap()); } } @@ -2918,7 +2914,7 @@ fn add_upstream_rust_crates( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, &bundled_libs, cnum, @@ -2933,11 +2929,11 @@ fn add_upstream_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, ) { - for &cnum in &codegen_results.crate_info.used_crates { + for &cnum in &crate_info.used_crates { // Static libraries are not linked here, they are linked in `add_upstream_rust_crates`. // FIXME: Merge this function to `add_upstream_rust_crates` so that all native libraries // are linked together with their respective upstream crates, and in their originally @@ -2956,7 +2952,7 @@ fn add_upstream_native_libraries( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, &Default::default(), cnum, @@ -3021,19 +3017,18 @@ fn add_static_crate( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, cnum: CrateNum, bundled_lib_file_names: &FxIndexSet, ) { - let src = &codegen_results.crate_info.used_crate_source[&cnum]; + let src = &crate_info.used_crate_source[&cnum]; let cratepath = src.rlib.as_ref().unwrap(); let mut link_upstream = |path: &Path| cmd.link_staticlib_by_path(&rehome_lib_path(sess, path), false); - if !are_upstream_rust_objects_already_included(sess) - || ignored_for_lto(sess, &codegen_results.crate_info, cnum) + if !are_upstream_rust_objects_already_included(sess) || ignored_for_lto(sess, crate_info, cnum) { link_upstream(cratepath); return; @@ -3048,8 +3043,7 @@ fn add_static_crate( let canonical_name = name.replace('-', "_"); let upstream_rust_objects_already_included = are_upstream_rust_objects_already_included(sess); - let is_builtins = - sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum); + let is_builtins = sess.target.no_builtins || !crate_info.is_no_builtins.contains(&cnum); let mut archive = archive_builder_builder.new_archive_builder(sess); if let Err(error) = archive.add_archive( diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 9898c1296142a..b501a35389cf8 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -42,8 +42,8 @@ use crate::back::lto::check_lto_allowed; use crate::errors::ErrorCreatingRemarkDir; use crate::traits::*; use crate::{ - CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, - errors, + CachedModuleCodegen, CodegenResults, CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, + ModuleKind, errors, }; const PRE_LTO_BC_EXT: &str = "pre-lto.bc"; @@ -394,16 +394,8 @@ fn generate_thin_lto_work( .collect() } -pub struct CompiledModules { - pub modules: Vec, - pub allocator_module: Option, -} - enum MaybeLtoModules { - NoLto { - modules: Vec, - allocator_module: Option, - }, + NoLto(CompiledModules), FatLto { cgcx: CodegenContext, exported_symbols_for_lto: Arc>, @@ -1818,12 +1810,12 @@ fn start_executing_work( } } - Ok(MaybeLtoModules::NoLto { + Ok(MaybeLtoModules::NoLto(CompiledModules { modules: compiled_modules, allocator_module: allocator_module.map(|allocator_module| { B::codegen(&cgcx, &prof, &shared_emitter, allocator_module, &allocator_config) }), - }) + })) }) .expect("failed to spawn coordinator thread"); @@ -2170,9 +2162,9 @@ impl OngoingCodegen { // Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics let compiled_modules = catch_fatal_errors(|| match maybe_lto_modules { - MaybeLtoModules::NoLto { modules, allocator_module } => { + MaybeLtoModules::NoLto(compiled_modules) => { drop(shared_emitter); - CompiledModules { modules, allocator_module } + compiled_modules } MaybeLtoModules::FatLto { cgcx, @@ -2256,15 +2248,7 @@ impl OngoingCodegen { self.backend.print_statistics() } - ( - CodegenResults { - crate_info: self.crate_info, - - modules: compiled_modules.modules, - allocator_module: compiled_modules.allocator_module, - }, - work_products, - ) + (CodegenResults { compiled_modules, crate_info: self.crate_info }, work_products) } pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) { diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index c7e90d3b3c330..4fcf6392a4933 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -252,9 +252,14 @@ pub struct TargetConfig { #[derive(Encodable, Decodable)] pub struct CodegenResults { + pub compiled_modules: CompiledModules, + pub crate_info: CrateInfo, +} + +#[derive(Encodable, Decodable)] +pub struct CompiledModules { pub modules: Vec, pub allocator_module: Option, - pub crate_info: CrateInfo, } pub enum CodegenErrors { diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 60f2d4155d4bc..33a13b7cdbc26 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -18,7 +18,7 @@ use super::write::WriteBackendMethods; use crate::back::archive::ArArchiveBuilderBuilder; use crate::back::link::link_binary; use crate::back::write::TargetMachineFactoryFn; -use crate::{CodegenResults, ModuleCodegen, TargetConfig}; +use crate::{CodegenResults, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; pub trait BackendTypes { type Function: CodegenObject; @@ -121,14 +121,16 @@ pub trait CodegenBackend { fn link( &self, sess: &Session, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, ) { link_binary( sess, &ArArchiveBuilderBuilder, - codegen_results, + compiled_modules, + crate_info, metadata, outputs, self.name(), diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 38a11b427c1f6..c426c6d4143f2 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -583,7 +583,13 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { }; } }; - compiler.codegen_backend.link(sess, codegen_results, metadata, &outputs); + compiler.codegen_backend.link( + sess, + codegen_results.compiled_modules, + codegen_results.crate_info, + metadata, + &outputs, + ); } else { dcx.emit_fatal(RlinkNotAFile {}); } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 15addd2407857..25e8494a6df00 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -8,7 +8,7 @@ use std::{env, fs, iter}; use rustc_ast::{self as ast, CRATE_NODE_ID}; use rustc_attr_parsing::{AttributeParser, Early, ShouldEmit}; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CrateInfo}; +use rustc_codegen_ssa::{CodegenResults, CompiledModules, CrateInfo}; use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal, par_fns}; @@ -1228,8 +1228,7 @@ pub(crate) fn start_codegen<'tcx>( // Linker::link will skip join_codegen in case of a CodegenResults Any value. Box::new(CodegenResults { - modules: vec![], - allocator_module: None, + compiled_modules: CompiledModules { modules: vec![], allocator_module: None }, crate_info: CrateInfo::new(tcx, "".to_owned()), }) } else { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 3799485077ef4..23f9360fed9fc 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -112,6 +112,12 @@ impl Linker { let _timer = sess.prof.verbose_generic_activity("link_crate"); let _timing = sess.timings.section_guard(sess.dcx(), TimingSection::Linking); - codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames) + codegen_backend.link( + sess, + codegen_results.compiled_modules, + codegen_results.crate_info, + self.metadata, + &self.output_filenames, + ) } } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f1b80ec13a307..492fbf93c02c0 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -11,7 +11,7 @@ use rustc_codegen_ssa::back::archive::{ArArchiveBuilderBuilder, ArchiveBuilderBu use rustc_codegen_ssa::back::link::link_binary; use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CrateInfo, TargetConfig}; +use rustc_codegen_ssa::{CodegenResults, CompiledModules, CrateInfo, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::sync; @@ -403,8 +403,7 @@ impl CodegenBackend for DummyCodegenBackend { fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { Box::new(CodegenResults { - modules: vec![], - allocator_module: None, + compiled_modules: CompiledModules { modules: vec![], allocator_module: None }, crate_info: CrateInfo::new(tcx, String::new()), }) } @@ -421,17 +420,15 @@ impl CodegenBackend for DummyCodegenBackend { fn link( &self, sess: &Session, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, ) { // JUSTIFICATION: TyCtxt no longer available here #[allow(rustc::bad_opt_access)] - if let Some(&crate_type) = codegen_results - .crate_info - .crate_types - .iter() - .find(|&&crate_type| crate_type != CrateType::Rlib) + if let Some(&crate_type) = + crate_info.crate_types.iter().find(|&&crate_type| crate_type != CrateType::Rlib) && outputs.outputs.should_link() { sess.dcx().fatal(format!( @@ -442,7 +439,8 @@ impl CodegenBackend for DummyCodegenBackend { link_binary( sess, &DummyArchiveBuilderBuilder, - codegen_results, + compiled_modules, + crate_info, metadata, outputs, self.name(), diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index c15c2dea4c196..2cfbe740eb317 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -18,7 +18,7 @@ extern crate rustc_target; use std::any::Any; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CrateInfo}; +use rustc_codegen_ssa::{CodegenResults, CompiledModules, CrateInfo}; use rustc_data_structures::fx::FxIndexMap; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -35,8 +35,7 @@ impl CodegenBackend for TheBackend { fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { Box::new(CodegenResults { - modules: vec![], - allocator_module: None, + compiled_modules: CompiledModules { modules: vec![], allocator_module: None }, crate_info: CrateInfo::new(tcx, "fake_target_cpu".to_string()), }) } @@ -56,7 +55,8 @@ impl CodegenBackend for TheBackend { fn link( &self, sess: &Session, - codegen_results: CodegenResults, + _compiled_modules: CompiledModules, + crate_info: CrateInfo, _metadata: EncodedMetadata, outputs: &OutputFilenames, ) { @@ -65,7 +65,7 @@ impl CodegenBackend for TheBackend { use rustc_session::config::{CrateType, OutFileName}; use rustc_session::output::out_filename; - let crate_name = codegen_results.crate_info.local_crate_name; + let crate_name = crate_info.local_crate_name; for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::Rlib { sess.dcx().fatal(format!("Crate type is {:?}", crate_type)); From 5aa980e6dcbb477f7e73e6e374b18d3020875fcf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Oct 2025 15:33:06 +0000 Subject: [PATCH 32/35] Replace CodegenResults with CompiledModules This is already CodegenResults without CrateInfo. The driver can calculate the CrateInfo and pass it by-ref to the backend. Using CompiledModules makes it a bit easier to move some other things out of the backend as will be necessary for moving LTO to the link phase. --- .../rustc_codegen_cranelift/src/driver/aot.rs | 15 +++--------- .../rustc_codegen_cranelift/src/driver/jit.rs | 13 +++++----- compiler/rustc_codegen_cranelift/src/lib.rs | 17 +++++++++---- compiler/rustc_codegen_gcc/src/lib.rs | 13 +++++----- compiler/rustc_codegen_llvm/src/lib.rs | 22 ++++++++--------- compiler/rustc_codegen_ssa/src/back/write.rs | 16 +++++-------- compiler/rustc_codegen_ssa/src/base.rs | 4 ++-- compiler/rustc_codegen_ssa/src/lib.rs | 24 +++++++++---------- .../rustc_codegen_ssa/src/traits/backend.rs | 10 ++++---- compiler/rustc_driver_impl/src/lib.rs | 18 ++++++-------- compiler/rustc_interface/src/passes.rs | 17 +++++++------ compiler/rustc_interface/src/queries.rs | 21 +++++++++------- compiler/rustc_interface/src/util.rs | 15 ++++++------ .../codegen-backend/auxiliary/the_backend.rs | 19 ++++++++------- tests/ui/rmeta/no_optimized_mir.rs | 1 + tests/ui/rmeta/no_optimized_mir.stderr | 4 +++- 16 files changed, 114 insertions(+), 115 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 7a736de967d21..79a3214568082 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -12,7 +12,7 @@ use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; use rustc_codegen_ssa::back::write::produce_final_output_artifacts; use rustc_codegen_ssa::base::determine_cgu_reuse; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, CompiledModules, CrateInfo, ModuleKind}; +use rustc_codegen_ssa::{CompiledModule, CompiledModules, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; @@ -54,7 +54,6 @@ impl HashStable for OngoingModuleCodegen { pub(crate) struct OngoingCodegen { modules: Vec, allocator_module: Option, - crate_info: CrateInfo, concurrency_limiter: ConcurrencyLimiter, } @@ -63,7 +62,7 @@ impl OngoingCodegen { self, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { let mut work_products = FxIndexMap::default(); let mut modules = vec![]; let disable_incr_cache = disable_incr_cache(); @@ -126,7 +125,7 @@ impl OngoingCodegen { produce_final_output_artifacts(sess, &compiled_modules, outputs); - (CodegenResults { compiled_modules, crate_info: self.crate_info }, work_products) + (compiled_modules, work_products) } } @@ -475,13 +474,6 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option { } pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { - // FIXME handle `-Ctarget-cpu=native` - let target_cpu = match tcx.sess.opts.cg.target_cpu { - Some(ref name) => name, - None => tcx.sess.target.cpu.as_ref(), - } - .to_owned(); - let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; if tcx.dep_graph.is_fully_enabled() { @@ -541,7 +533,6 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { Box::new(OngoingCodegen { modules, allocator_module, - crate_info: CrateInfo::new(tcx, target_cpu), concurrency_limiter: concurrency_limiter.0, }) } diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 3a8ca25a5fc00..9bbc338a8e07c 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -16,13 +16,14 @@ use crate::debuginfo::TypeDebugContext; use crate::prelude::*; use crate::unwind_module::UnwindModule; -fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option) { - let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); - +fn create_jit_module( + tcx: TyCtxt<'_>, + crate_info: &CrateInfo, +) -> (UnwindModule, Option) { let isa = crate::build_isa(tcx.sess, true); let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names()); crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); - jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info)); + jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info.clone())); let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name"); @@ -32,14 +33,14 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option, jit_args: Vec) -> ! { +pub(crate) fn run_jit(tcx: TyCtxt<'_>, crate_info: &CrateInfo, jit_args: Vec) -> ! { if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) { tcx.dcx().fatal("can't jit non-executable crate"); } let output_filenames = tcx.output_filenames(()); let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess); - let (mut jit_module, mut debug_context) = create_jit_module(tcx); + let (mut jit_module, mut debug_context) = create_jit_module(tcx, crate_info); let mut cached_context = Context::new(); let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 7bab07def63d1..82c2e91b4b0f7 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -40,7 +40,7 @@ use std::sync::Arc; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::settings::{self, Configurable}; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, TargetConfig}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig}; use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; @@ -200,12 +200,21 @@ impl CodegenBackend for CraneliftCodegenBackend { println!("Cranelift version: {}", cranelift_codegen::VERSION); } - fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { + fn target_cpu(&self, sess: &Session) -> String { + // FIXME handle `-Ctarget-cpu=native` + match sess.opts.cg.target_cpu { + Some(ref name) => name, + None => sess.target.cpu.as_ref(), + } + .to_owned() + } + + fn codegen_crate(&self, tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box { info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE)); let config = self.config.get().unwrap(); if config.jit_mode { #[cfg(feature = "jit")] - driver::jit::run_jit(tcx, config.jit_args.clone()); + driver::jit::run_jit(tcx, _crate_info, config.jit_args.clone()); #[cfg(not(feature = "jit"))] tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift"); @@ -219,7 +228,7 @@ impl CodegenBackend for CraneliftCodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { ongoing_codegen.downcast::().unwrap().join(sess, outputs) } } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index afb07f57ab7a7..529a5085c30f4 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -88,7 +88,7 @@ use rustc_codegen_ssa::back::write::{ use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; +use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::IntoDynSyncSend; @@ -287,11 +287,12 @@ impl CodegenBackend for GccCodegenBackend { |tcx, ()| gcc_util::global_gcc_features(tcx.sess) } - fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { - let target_cpu = target_cpu(tcx.sess); - let res = codegen_crate(self.clone(), tcx, target_cpu.to_string()); + fn target_cpu(&self, sess: &Session) -> String { + target_cpu(sess).to_owned() + } - Box::new(res) + fn codegen_crate(&self, tcx: TyCtxt<'_>, crate_info: &CrateInfo) -> Box { + Box::new(codegen_crate(self.clone(), tcx, crate_info)) } fn join_codegen( @@ -299,7 +300,7 @@ impl CodegenBackend for GccCodegenBackend { ongoing_codegen: Box, sess: &Session, _outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 5282b723c2b90..c03b0ac9157a8 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -33,9 +33,7 @@ use rustc_codegen_ssa::back::write::{ TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::{ - CodegenResults, CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig, -}; +use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; @@ -362,12 +360,12 @@ impl CodegenBackend for LlvmCodegenBackend { will_not_use_fallback } - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { - Box::new(rustc_codegen_ssa::base::codegen_crate( - LlvmCodegenBackend(()), - tcx, - crate::llvm_util::target_cpu(tcx.sess).to_string(), - )) + fn target_cpu(&self, sess: &Session) -> String { + crate::llvm_util::target_cpu(sess).to_string() + } + + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box { + Box::new(rustc_codegen_ssa::base::codegen_crate(LlvmCodegenBackend(()), tcx, crate_info)) } fn join_codegen( @@ -375,8 +373,8 @@ impl CodegenBackend for LlvmCodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { - let (codegen_results, work_products) = ongoing_codegen + ) -> (CompiledModules, FxIndexMap) { + let (compiled_modules, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") .join(sess); @@ -388,7 +386,7 @@ impl CodegenBackend for LlvmCodegenBackend { }); } - (codegen_results, work_products) + (compiled_modules, work_products) } fn link( diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index b501a35389cf8..0d210eacf9a83 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -42,8 +42,8 @@ use crate::back::lto::check_lto_allowed; use crate::errors::ErrorCreatingRemarkDir; use crate::traits::*; use crate::{ - CachedModuleCodegen, CodegenResults, CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, - ModuleKind, errors, + CachedModuleCodegen, CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, ModuleKind, + errors, }; const PRE_LTO_BC_EXT: &str = "pre-lto.bc"; @@ -435,15 +435,13 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { pub(crate) fn start_async_codegen( backend: B, tcx: TyCtxt<'_>, - target_cpu: String, + crate_info: &CrateInfo, allocator_module: Option>, ) -> OngoingCodegen { let (coordinator_send, coordinator_receive) = channel(); let no_builtins = find_attr!(tcx, crate, NoBuiltins); - let crate_info = CrateInfo::new(tcx, target_cpu); - let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins); let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins); @@ -453,7 +451,7 @@ pub(crate) fn start_async_codegen( let coordinator_thread = start_executing_work( backend.clone(), tcx, - &crate_info, + crate_info, shared_emitter, codegen_worker_send, coordinator_receive, @@ -465,7 +463,6 @@ pub(crate) fn start_async_codegen( OngoingCodegen { backend, - crate_info, codegen_worker_receive, shared_emitter_main, @@ -2131,7 +2128,6 @@ impl Drop for Coordinator { pub struct OngoingCodegen { pub backend: B, - pub crate_info: CrateInfo, pub output_filenames: Arc, // Field order below is intended to terminate the coordinator thread before two fields below // drop and prematurely close channels used by coordinator thread. See `Coordinator`'s @@ -2142,7 +2138,7 @@ pub struct OngoingCodegen { } impl OngoingCodegen { - pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap) { + pub fn join(self, sess: &Session) -> (CompiledModules, FxIndexMap) { self.shared_emitter_main.check(sess, true); let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { @@ -2248,7 +2244,7 @@ impl OngoingCodegen { self.backend.print_statistics() } - (CodegenResults { compiled_modules, crate_info: self.crate_info }, work_products) + (compiled_modules, work_products) } pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 3939f145df881..609f54b7a1cf4 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -681,7 +681,7 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec( backend: B, tcx: TyCtxt<'_>, - target_cpu: String, + crate_info: &CrateInfo, ) -> OngoingCodegen { if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() { // The target has no default cpu, but none is set explicitly @@ -719,7 +719,7 @@ pub fn codegen_crate( None }; - let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu, allocator_module); + let ongoing_codegen = start_async_codegen(backend.clone(), tcx, crate_info, allocator_module); // For better throughput during parallel processing by LLVM, we used to sort // CGUs largest to smallest. This would lead to better thread utilization diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 4fcf6392a4933..6a0a9e7d51bed 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -209,7 +209,8 @@ impl From<&cstore::NativeLib> for NativeLib { /// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own /// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource` /// and the corresponding properties without referencing information outside of a `CrateInfo`. -#[derive(Debug, Encodable, Decodable)] +// rustc_codegen_cranelift needs a Clone impl for its jit mode, which isn't tested in rust CI +#[derive(Clone, Debug, Encodable, Decodable)] pub struct CrateInfo { pub target_cpu: String, pub target_features: Vec, @@ -250,12 +251,6 @@ pub struct TargetConfig { pub has_reliable_f128_math: bool, } -#[derive(Encodable, Decodable)] -pub struct CodegenResults { - pub compiled_modules: CompiledModules, - pub crate_info: CrateInfo, -} - #[derive(Encodable, Decodable)] pub struct CompiledModules { pub modules: Vec, @@ -298,11 +293,12 @@ pub fn looks_like_rust_object_file(filename: &str) -> bool { const RLINK_VERSION: u32 = 1; const RLINK_MAGIC: &[u8] = b"rustlink"; -impl CodegenResults { +impl CompiledModules { pub fn serialize_rlink( sess: &Session, rlink_file: &Path, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, outputs: &OutputFilenames, ) -> Result { @@ -312,7 +308,8 @@ impl CodegenResults { // Encoder's inner representation of `u32`. encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes()); encoder.emit_str(sess.cfg_version); - Encodable::encode(codegen_results, &mut encoder); + Encodable::encode(compiled_modules, &mut encoder); + Encodable::encode(crate_info, &mut encoder); Encodable::encode(metadata, &mut encoder); Encodable::encode(outputs, &mut encoder); encoder.finish().map_err(|(_path, err)| err) @@ -321,7 +318,7 @@ impl CodegenResults { pub fn deserialize_rlink( sess: &Session, data: Vec, - ) -> Result<(Self, EncodedMetadata, OutputFilenames), CodegenErrors> { + ) -> Result<(Self, CrateInfo, EncodedMetadata, OutputFilenames), CodegenErrors> { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { @@ -351,10 +348,11 @@ impl CodegenResults { }); } - let codegen_results = CodegenResults::decode(&mut decoder); + let compiled_modules = CompiledModules::decode(&mut decoder); + let crate_info = CrateInfo::decode(&mut decoder); let metadata = EncodedMetadata::decode(&mut decoder); let outputs = OutputFilenames::decode(&mut decoder); - Ok((codegen_results, metadata, outputs)) + Ok((compiled_modules, crate_info, metadata, outputs)) } } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 33a13b7cdbc26..8df1ecc0fff57 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -18,7 +18,7 @@ use super::write::WriteBackendMethods; use crate::back::archive::ArArchiveBuilderBuilder; use crate::back::link::link_binary; use crate::back::write::TargetMachineFactoryFn; -use crate::{CodegenResults, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; +use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; pub trait BackendTypes { type Function: CodegenObject; @@ -103,7 +103,9 @@ pub trait CodegenBackend { fn provide(&self, _providers: &mut Providers) {} - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box; + fn target_cpu(&self, sess: &Session) -> String; + + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box; /// This is called on the returned `Box` from [`codegen_crate`](Self::codegen_crate) /// @@ -115,9 +117,9 @@ pub trait CodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap); + ) -> (CompiledModules, FxIndexMap); - /// This is called on the returned [`CodegenResults`] from [`join_codegen`](Self::join_codegen). + /// This is called on the returned [`CompiledModules`] from [`join_codegen`](Self::join_codegen). fn link( &self, sess: &Session, diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index c426c6d4143f2..86d902b1c6993 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -28,7 +28,7 @@ use std::{env, str}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenErrors, CodegenResults}; +use rustc_codegen_ssa::{CodegenErrors, CompiledModules}; use rustc_data_structures::profiling::{ TimePassesFormat, get_resident_set_size, print_time_passes_entry, }; @@ -556,9 +556,11 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { let rlink_data = fs::read(file).unwrap_or_else(|err| { dcx.emit_fatal(RlinkUnableToRead { err }); }); - let (codegen_results, metadata, outputs) = - match CodegenResults::deserialize_rlink(sess, rlink_data) { - Ok((codegen, metadata, outputs)) => (codegen, metadata, outputs), + let (compiled_modules, crate_info, metadata, outputs) = + match CompiledModules::deserialize_rlink(sess, rlink_data) { + Ok((codegen, crate_info, metadata, outputs)) => { + (codegen, crate_info, metadata, outputs) + } Err(err) => { match err { CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType), @@ -583,13 +585,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { }; } }; - compiler.codegen_backend.link( - sess, - codegen_results.compiled_modules, - codegen_results.crate_info, - metadata, - &outputs, - ); + compiler.codegen_backend.link(sess, compiled_modules, crate_info, metadata, &outputs); } else { dcx.emit_fatal(RlinkNotAFile {}); } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 25e8494a6df00..5d4db9aef003c 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -8,7 +8,7 @@ use std::{env, fs, iter}; use rustc_ast::{self as ast, CRATE_NODE_ID}; use rustc_attr_parsing::{AttributeParser, Early, ShouldEmit}; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CompiledModules, CrateInfo}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal, par_fns}; @@ -1194,7 +1194,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { pub(crate) fn start_codegen<'tcx>( codegen_backend: &dyn CodegenBackend, tcx: TyCtxt<'tcx>, -) -> (Box, EncodedMetadata) { +) -> (Box, CrateInfo, EncodedMetadata) { tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen); // Hook for tests. @@ -1221,18 +1221,17 @@ pub(crate) fn start_codegen<'tcx>( let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx); - let codegen = tcx.sess.time("codegen_crate", move || { + let crate_info = CrateInfo::new(tcx, codegen_backend.target_cpu(tcx.sess)); + + let codegen = tcx.sess.time("codegen_crate", || { if tcx.sess.opts.unstable_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() { // Skip crate items and just output metadata in -Z no-codegen mode. tcx.sess.dcx().abort_if_errors(); // Linker::link will skip join_codegen in case of a CodegenResults Any value. - Box::new(CodegenResults { - compiled_modules: CompiledModules { modules: vec![], allocator_module: None }, - crate_info: CrateInfo::new(tcx, "".to_owned()), - }) + Box::new(CompiledModules { modules: vec![], allocator_module: None }) } else { - codegen_backend.codegen_crate(tcx) + codegen_backend.codegen_crate(tcx, &crate_info) } }); @@ -1244,7 +1243,7 @@ pub(crate) fn start_codegen<'tcx>( tcx.sess.code_stats.print_type_sizes(); } - (codegen, metadata) + (codegen, crate_info, metadata) } /// Compute and validate the crate name. diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 23f9360fed9fc..f4fcd4471d3fd 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -1,8 +1,8 @@ use std::any::Any; use std::sync::Arc; -use rustc_codegen_ssa::CodegenResults; use rustc_codegen_ssa::traits::CodegenBackend; +use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::svh::Svh; use rustc_errors::timings::TimingSection; @@ -21,6 +21,7 @@ pub struct Linker { output_filenames: Arc, // Only present when incr. comp. is enabled. crate_hash: Option, + crate_info: CrateInfo, metadata: EncodedMetadata, ongoing_codegen: Box, } @@ -30,7 +31,7 @@ impl Linker { tcx: TyCtxt<'_>, codegen_backend: &dyn CodegenBackend, ) -> Linker { - let (ongoing_codegen, metadata) = passes::start_codegen(codegen_backend, tcx); + let (ongoing_codegen, crate_info, metadata) = passes::start_codegen(codegen_backend, tcx); Linker { dep_graph: tcx.dep_graph.clone(), @@ -40,16 +41,17 @@ impl Linker { } else { None }, + crate_info, metadata, ongoing_codegen, } } pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) { - let (codegen_results, mut work_products) = sess.time("finish_ongoing_codegen", || { - match self.ongoing_codegen.downcast::() { + let (compiled_modules, mut work_products) = sess.time("finish_ongoing_codegen", || { + match self.ongoing_codegen.downcast::() { // This was a check only build - Ok(codegen_results) => (*codegen_results, IndexMap::default()), + Ok(compiled_modules) => (*compiled_modules, IndexMap::default()), Err(ongoing_codegen) => { codegen_backend.join_codegen(ongoing_codegen, sess, &self.output_filenames) @@ -97,10 +99,11 @@ impl Linker { if sess.opts.unstable_opts.no_link { let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT); - CodegenResults::serialize_rlink( + CompiledModules::serialize_rlink( sess, &rlink_file, - &codegen_results, + &compiled_modules, + &self.crate_info, &self.metadata, &self.output_filenames, ) @@ -114,8 +117,8 @@ impl Linker { let _timing = sess.timings.section_guard(sess.dcx(), TimingSection::Linking); codegen_backend.link( sess, - codegen_results.compiled_modules, - codegen_results.crate_info, + compiled_modules, + self.crate_info, self.metadata, &self.output_filenames, ) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 492fbf93c02c0..bacdad25c50b3 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -11,7 +11,7 @@ use rustc_codegen_ssa::back::archive::{ArArchiveBuilderBuilder, ArchiveBuilderBu use rustc_codegen_ssa::back::link::link_binary; use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CompiledModules, CrateInfo, TargetConfig}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::sync; @@ -401,11 +401,12 @@ impl CodegenBackend for DummyCodegenBackend { vec![CrateType::Rlib, CrateType::Executable] } - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { - Box::new(CodegenResults { - compiled_modules: CompiledModules { modules: vec![], allocator_module: None }, - crate_info: CrateInfo::new(tcx, String::new()), - }) + fn target_cpu(&self, _sess: &Session) -> String { + String::new() + } + + fn codegen_crate<'tcx>(&self, _tcx: TyCtxt<'tcx>, _crate_info: &CrateInfo) -> Box { + Box::new(CompiledModules { modules: vec![], allocator_module: None }) } fn join_codegen( @@ -413,7 +414,7 @@ impl CodegenBackend for DummyCodegenBackend { ongoing_codegen: Box, _sess: &Session, _outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default()) } diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 2cfbe740eb317..5dd11b0a016e3 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -18,7 +18,7 @@ extern crate rustc_target; use std::any::Any; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CompiledModules, CrateInfo}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_data_structures::fx::FxIndexMap; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -33,11 +33,12 @@ impl CodegenBackend for TheBackend { "the-backend" } - fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { - Box::new(CodegenResults { - compiled_modules: CompiledModules { modules: vec![], allocator_module: None }, - crate_info: CrateInfo::new(tcx, "fake_target_cpu".to_string()), - }) + fn target_cpu(&self, _sess: &Session) -> String { + "fake_target_cpu".to_owned() + } + + fn codegen_crate(&self, _tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box { + Box::new(CompiledModules { modules: vec![], allocator_module: None }) } fn join_codegen( @@ -45,10 +46,10 @@ impl CodegenBackend for TheBackend { ongoing_codegen: Box, _sess: &Session, _outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { let codegen_results = ongoing_codegen - .downcast::() - .expect("in join_codegen: ongoing_codegen is not a CodegenResults"); + .downcast::() + .expect("in join_codegen: ongoing_codegen is not a CompiledModules"); (*codegen_results, FxIndexMap::default()) } diff --git a/tests/ui/rmeta/no_optimized_mir.rs b/tests/ui/rmeta/no_optimized_mir.rs index c8ed00b039b23..dbf612cd03cc7 100644 --- a/tests/ui/rmeta/no_optimized_mir.rs +++ b/tests/ui/rmeta/no_optimized_mir.rs @@ -10,4 +10,5 @@ fn main() { rmeta_meta::missing_optimized_mir(); } +//~? ERROR crate `rmeta_meta` required to be available in rlib format, but was not found in this form //~? ERROR missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta` diff --git a/tests/ui/rmeta/no_optimized_mir.stderr b/tests/ui/rmeta/no_optimized_mir.stderr index 254f100aa7b5e..91aa98172fe56 100644 --- a/tests/ui/rmeta/no_optimized_mir.stderr +++ b/tests/ui/rmeta/no_optimized_mir.stderr @@ -1,3 +1,5 @@ +error: crate `rmeta_meta` required to be available in rlib format, but was not found in this form + error: missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta` | note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled with `--emit=metadata`?) @@ -6,5 +8,5 @@ note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled w LL | pub fn missing_optimized_mir() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors From 158ac1a10b612cc73c633fdf7d4249ef1116ba96 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Mon, 2 Mar 2026 18:11:13 -0800 Subject: [PATCH 33/35] Comments and docs: add missing periods to "ie." "i.e." is short for the Latin "id est" and thus both letters should be followed by periods. --- compiler/rustc_hir/src/def.rs | 2 +- compiler/rustc_lint/src/ptr_nulls.rs | 2 +- .../src/traits/specialization_graph.rs | 4 ++-- .../rustc_mir_transform/src/elaborate_drop.rs | 2 +- compiler/rustc_mir_transform/src/ref_prop.rs | 2 +- compiler/rustc_mir_transform/src/ssa.rs | 4 ++-- compiler/rustc_resolve/src/diagnostics.rs | 18 +++++++++--------- compiler/rustc_resolve/src/imports.rs | 2 +- compiler/rustc_session/src/config/cfg.rs | 2 +- .../infer/nice_region_error/find_anon_type.rs | 2 +- library/std/src/fs.rs | 4 ++-- src/doc/rustc/src/check-cfg.md | 2 +- .../clippy/clippy_lints/src/trait_bounds.rs | 2 +- .../miri/tests/fail/shims/shim_arg_size.rs | 2 +- .../rust-analyzer/crates/base-db/src/input.rs | 2 +- .../crates/hir-def/src/visibility.rs | 4 ++-- tests/run-make/print-cfg/rmake.rs | 2 +- tests/run-make/remap-path-prefix-std/rmake.rs | 2 +- .../defaults-in-other-trait-items.rs | 2 +- tests/ui/associated-types/issue-54182-1.rs | 2 +- .../ui/rfcs/rfc-2008-non-exhaustive/struct.rs | 2 +- 21 files changed, 33 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 394622654cf88..3959ee7f94128 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -371,7 +371,7 @@ impl DefKind { ) } - /// Whether the corresponding item has generic parameters, ie. the `generics_of` query works. + /// Whether the corresponding item has generic parameters, i.e. the `generics_of` query works. pub fn has_generics(self) -> bool { match self { DefKind::AnonConst diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index 1e1bbf51fcb9b..34c569232fc0d 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -59,7 +59,7 @@ declare_lint! { declare_lint_pass!(PtrNullChecks => [USELESS_PTR_NULL_CHECKS, INVALID_NULL_ARGUMENTS]); /// This function checks if the expression is from a series of consecutive casts, -/// ie. `(my_fn as *const _ as *mut _).cast_mut()` and whether the original expression is either +/// i.e. `(my_fn as *const _ as *mut _).cast_mut()` and whether the original expression is either /// a fn ptr, a reference, or a function call whose definition is /// annotated with `#![rustc_never_returns_null_ptr]`. /// If this situation is present, the function returns the appropriate diagnostic. diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 6367c87b1aa95..c501682775524 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -175,7 +175,7 @@ pub struct LeafDef { /// The node in the specialization graph containing the definition of `item`. pub defining_node: Node, - /// The "top-most" (ie. least specialized) specialization graph node that finalized the + /// The "top-most" (i.e. least specialized) specialization graph node that finalized the /// definition of `item`. /// /// Example: @@ -210,7 +210,7 @@ impl LeafDef { } impl<'tcx> Ancestors<'tcx> { - /// Finds the bottom-most (ie. most specialized) definition of an associated + /// Finds the bottom-most (i.e. most specialized) definition of an associated /// item. pub fn leaf_def(mut self, tcx: TyCtxt<'tcx>, trait_item_def_id: DefId) -> Option { let mut finalizing_node = None; diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 655262af8f36a..7b8772eda2b38 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -160,7 +160,7 @@ where /// /// The passed `elaborator` is used to determine what should happen at the drop terminator. It /// decides whether the drop can be statically determined or whether it needs a dynamic drop flag, -/// and whether the drop is "open", ie. should be expanded to drop all subfields of the dropped +/// and whether the drop is "open", i.e. should be expanded to drop all subfields of the dropped /// value. /// /// When this returns, the MIR patch in the `elaborator` contains the necessary changes. diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 721a976eb910a..0c5d8913a8070 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -245,7 +245,7 @@ fn compute_replacement<'tcx>( debug!(?rvalue); match rvalue { // This is a copy, just use the value we have in store for the previous one. - // As we are visiting in `assignment_order`, ie. reverse postorder, `rhs` should + // As we are visiting in `assignment_order`, i.e. reverse postorder, `rhs` should // have been visited before. Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) => { if let Some(rhs) = place.as_local() diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index a56f04cf48422..4f9f2e5fabb93 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -25,7 +25,7 @@ pub(super) struct SsaLocals { assignment_order: Vec, /// Copy equivalence classes between locals. See `copy_classes` for documentation. copy_classes: IndexVec, - /// Number of "direct" uses of each local, ie. uses that are not dereferences. + /// Number of "direct" uses of each local, i.e. uses that are not dereferences. /// We ignore non-uses (Storage statements, debuginfo). direct_uses: IndexVec, /// Set of SSA locals that are immutably borrowed. @@ -314,7 +314,7 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { continue; } - // We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been + // We visit in `assignment_order`, i.e. reverse post-order, so `rhs` has been // visited before `local`, and we just have to copy the representing local. let head = copies[rhs]; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b3226b9f27699..c776020c21274 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2976,7 +2976,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { corrections.push((import.span, format!("{module_name}::{import_snippet}"))); } else { // Find the binding span (and any trailing commas and spaces). - // ie. `use a::b::{c, d, e};` + // i.e. `use a::b::{c, d, e};` // ^^^ let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( self.tcx.sess, @@ -2988,11 +2988,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut removal_span = binding_span; // If the binding span ended with a closing brace, as in the below example: - // ie. `use a::b::{c, d};` + // i.e. `use a::b::{c, d};` // ^ // Then expand the span of characters to remove to include the previous // binding's trailing comma. - // ie. `use a::b::{c, d};` + // i.e. `use a::b::{c, d};` // ^^^ if found_closing_brace && let Some(previous_span) = @@ -3008,7 +3008,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Find the span after the crate name and if it has nested imports immediately // after the crate name already. - // ie. `use a::b::{c, d};` + // i.e. `use a::b::{c, d};` // ^^^^^^^^^ // or `use a::{b, c, d}};` // ^^^^^^^^^^^ @@ -3172,16 +3172,16 @@ fn find_span_of_binding_until_next_binding( let source_map = sess.source_map(); // Find the span of everything after the binding. - // ie. `a, e};` or `a};` + // i.e. `a, e};` or `a};` let binding_until_end = binding_span.with_hi(use_span.hi()); // Find everything after the binding but not including the binding. - // ie. `, e};` or `};` + // i.e. `, e};` or `};` let after_binding_until_end = binding_until_end.with_lo(binding_span.hi()); // Keep characters in the span until we encounter something that isn't a comma or // whitespace. - // ie. `, ` or ``. + // i.e. `, ` or ``. // // Also note whether a closing brace character was encountered. If there // was, then later go backwards to remove any trailing commas that are left. @@ -3195,7 +3195,7 @@ fn find_span_of_binding_until_next_binding( }); // Combine the two spans. - // ie. `a, ` or `a`. + // i.e. `a, ` or `a`. // // Removing these would leave `issue_52891::{d, e};` or `issue_52891::{d, e, };` let span = binding_span.with_hi(after_binding_until_next_binding.hi()); @@ -3219,7 +3219,7 @@ fn extend_span_to_previous_binding(sess: &Session, binding_span: Span) -> Option let source_map = sess.source_map(); // `prev_source` will contain all of the source that came before the span. - // Then split based on a command and take the first (ie. closest to our span) + // Then split based on a command and take the first (i.e. closest to our span) // snippet. In the example, this is a space. let prev_source = source_map.span_to_prev_source(binding_span).ok()?; diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index f0527740a58c7..7696b4b220d6c 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -70,7 +70,7 @@ pub(crate) enum ImportKind<'ra> { decls: PerNS>>, /// `true` for `...::{self [as target]}` imports, `false` otherwise. type_ns_only: bool, - /// Did this import result from a nested import? ie. `use foo::{bar, baz};` + /// Did this import result from a nested import? i.e. `use foo::{bar, baz};` nested: bool, /// The ID of the `UseTree` that imported this `Import`. /// diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index cd0556de5c22c..ebbbe36878daa 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -328,7 +328,7 @@ impl CheckCfg { return; } - // for `#[cfg(foo)]` (ie. cfg value is none) + // for `#[cfg(foo)]` (i.e. cfg value is none) let no_values = || { let mut values = FxHashSet::default(); values.insert(None); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index 7d061e65df80b..739628f820653 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -160,7 +160,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { } // The visitor captures the corresponding `hir::Ty` of the anonymous region -// in the case of structs ie. `hir::TyKind::Path`. +// in the case of structs i.e. `hir::TyKind::Path`. // This visitor would be invoked for each lifetime corresponding to a struct, // and would walk the types like Vec in the above example and Ref looking for the HIR // where that lifetime appears. This allows us to highlight the diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index cf6f9594c0027..885bf376b98ad 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2680,7 +2680,7 @@ impl AsInner for DirEntry { /// /// This function will only ever return an error of kind `NotFound` if the given /// path does not exist. Note that the inverse is not true, -/// ie. if a path does not exist, its removal may fail for a number of reasons, +/// i.e. if a path does not exist, its removal may fail for a number of reasons, /// such as insufficient permissions. /// /// # Examples @@ -3150,7 +3150,7 @@ pub fn create_dir_all>(path: P) -> io::Result<()> { /// /// This function will only ever return an error of kind `NotFound` if the given /// path does not exist. Note that the inverse is not true, -/// ie. if a path does not exist, its removal may fail for a number of reasons, +/// i.e. if a path does not exist, its removal may fail for a number of reasons, /// such as insufficient permissions. /// /// # Examples diff --git a/src/doc/rustc/src/check-cfg.md b/src/doc/rustc/src/check-cfg.md index 4caeaa106b495..dfe036bf1bb19 100644 --- a/src/doc/rustc/src/check-cfg.md +++ b/src/doc/rustc/src/check-cfg.md @@ -53,7 +53,7 @@ To check for the _none_ value (ie `#[cfg(foo)]`) one can use the `none()` predic `values()`: `values(none())`. It can be followed or preceded by any number of `"value"`. To enable checking of values, but to provide an *none*/empty set of expected values -(ie. expect `#[cfg(name)]`), use these forms: +(i.e. expect `#[cfg(name)]`), use these forms: ```bash rustc --check-cfg 'cfg(name)' diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 352b8526b0217..8191857755052 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { // special handling for self trait bounds as these are not considered generics - // ie. trait Foo: Display {} + // i.e. trait Foo: Display {} if let Item { kind: ItemKind::Trait(_, _, _, _, _, bounds, ..), .. diff --git a/src/tools/miri/tests/fail/shims/shim_arg_size.rs b/src/tools/miri/tests/fail/shims/shim_arg_size.rs index 3d7bc25bf5d31..4129dec6c4d34 100644 --- a/src/tools/miri/tests/fail/shims/shim_arg_size.rs +++ b/src/tools/miri/tests/fail/shims/shim_arg_size.rs @@ -1,6 +1,6 @@ fn main() { extern "C" { - // Use the wrong type (ie. not `i32`) for the `c` argument. + // Use the wrong type (i.e. not `i32`) for the `c` argument. fn memchr(s: *const std::ffi::c_void, c: u8, n: usize) -> *mut std::ffi::c_void; } diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 94793a3618e18..151aba82a2033 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -742,7 +742,7 @@ impl CrateGraphBuilder { deps.into_iter() } - /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate + /// Returns all crates in the graph, sorted in topological order (i.e. dependencies of a crate /// come before the crate itself). fn crates_in_topological_order(&self) -> Vec { let mut res = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index a1645de6ec236..ccd001df69b41 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -146,7 +146,7 @@ impl Visibility { /// Returns the most permissive visibility of `self` and `other`. /// - /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only + /// If there is no subset relation between `self` and `other`, returns `None` (i.e. they're only /// visible in unrelated modules). pub(crate) fn max( self, @@ -212,7 +212,7 @@ impl Visibility { /// Returns the least permissive visibility of `self` and `other`. /// - /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only + /// If there is no subset relation between `self` and `other`, returns `None` (i.e. they're only /// visible in unrelated modules). pub(crate) fn min( self, diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs index 7b8b760ea333b..a5df237b7fddc 100644 --- a/tests/run-make/print-cfg/rmake.rs +++ b/tests/run-make/print-cfg/rmake.rs @@ -1,7 +1,7 @@ //! This checks the output of `--print=cfg` //! //! Specifically it checks that output is correctly formatted -//! (ie. no duplicated cfgs, values are between "", names are not). +//! (i.e. no duplicated cfgs, values are between "", names are not). //! //! It also checks that some targets have the correct set cfgs. diff --git a/tests/run-make/remap-path-prefix-std/rmake.rs b/tests/run-make/remap-path-prefix-std/rmake.rs index f5179038a9b11..bf8bdf039f347 100644 --- a/tests/run-make/remap-path-prefix-std/rmake.rs +++ b/tests/run-make/remap-path-prefix-std/rmake.rs @@ -1,5 +1,5 @@ // This test makes sure that we do not leak paths to the checkout -// (ie. /checkout in CI) in the distributed `libstd` debuginfo. +// (i.e. /checkout in CI) in the distributed `libstd` debuginfo. // // This test only runs on Linux and dist builder (or with `rust.remap-debuginfo = true` // set in your `bootstrap.toml`). diff --git a/tests/ui/associated-types/defaults-in-other-trait-items.rs b/tests/ui/associated-types/defaults-in-other-trait-items.rs index f263809552fdf..3de64e0d0db6d 100644 --- a/tests/ui/associated-types/defaults-in-other-trait-items.rs +++ b/tests/ui/associated-types/defaults-in-other-trait-items.rs @@ -1,7 +1,7 @@ #![feature(associated_type_defaults)] // Associated type defaults may not be assumed inside the trait defining them. -// ie. they only resolve to `::A`, not the actual type `()` +// i.e. they only resolve to `::A`, not the actual type `()` trait Tr { type A = (); //~ NOTE associated type defaults can't be assumed inside the trait defining them diff --git a/tests/ui/associated-types/issue-54182-1.rs b/tests/ui/associated-types/issue-54182-1.rs index 1ebcca758c0fc..57cf93dfee92f 100644 --- a/tests/ui/associated-types/issue-54182-1.rs +++ b/tests/ui/associated-types/issue-54182-1.rs @@ -3,7 +3,7 @@ // Tests that the return type of trait methods is correctly normalized when // checking that a method in an impl matches the trait definition when the // return type involves a defaulted associated type. -// ie. the trait has a method with return type `-> Self::R`, and `type R = ()`, +// i.e. the trait has a method with return type `-> Self::R`, and `type R = ()`, // but the impl leaves out the return type (resulting in `()`). // Note that specialization is not involved in this test; no items in // implementations may be overridden. If they were, the normalization wouldn't diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs index b3953c2e8d029..eb1da3f6ecf3b 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs @@ -39,7 +39,7 @@ fn main() { // Everything below this is expected to compile successfully. // We only test matching here as we cannot create non-exhaustive -// structs from another crate. ie. they'll never pass in run-pass tests. +// structs from another crate. i.e. they'll never pass in run-pass tests. fn match_structs(ns: NormalStruct, ts: TupleStruct, us: UnitStruct) { let NormalStruct { first_field, second_field, .. } = ns; From 1d678f6b0859ea25c2abc22eb4104a025a5737e4 Mon Sep 17 00:00:00 2001 From: Deepesh Varatharajan Date: Mon, 2 Mar 2026 04:22:23 -0800 Subject: [PATCH 34/35] Update call-llvm-intrinsics test for Rust 1.94.0 IR and multi-target CI Rust 1.94 now passes constants directly to llvm.sqrt.f32 instead of storing/loading via the stack. - Updated the FileCheck pattern to match the new IR: // CHECK: call float @llvm.sqrt.f32(float 4.000000e+00) The test intent is unchanged: it still ensures the intrinsic is emitted as a 'call' (not 'invoke'). - Removed unnecessary local variables and Drop usage to work in `#![no_core]` mode with minicore. - Added required crate attributes: #![feature(no_core, lang_items)] #![no_std] #![no_core] - Replaced `//@ only-riscv64` (host-based execution) with explicit revisions for: riscv32gc-unknown-linux-gnu riscv64gc-unknown-linux-gnu This ensures deterministic multi-target coverage in CI without relying on the host architecture. - Added `//@ needs-llvm-components: riscv` and `//@ min-llvm-version: 21` for CI compatibility. Signed-off-by: Deepesh Varatharajan --- .../riscv-abi/call-llvm-intrinsics.rs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs b/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs index e72a649a530a8..fb520d38df3ca 100644 --- a/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs +++ b/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs @@ -1,17 +1,20 @@ +//@ add-minicore //@ compile-flags: -C no-prepopulate-passes - -//@ only-riscv64 +//@ revisions: riscv32gc riscv64gc +//@ [riscv32gc] compile-flags: --target riscv32gc-unknown-linux-gnu +//@ [riscv32gc] needs-llvm-components: riscv +//@ [riscv64gc] compile-flags: --target riscv64gc-unknown-linux-gnu +//@ [riscv64gc] needs-llvm-components: riscv +//@ min-llvm-version: 21 #![feature(link_llvm_intrinsics)] +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] #![crate_type = "lib"] -struct A; - -impl Drop for A { - fn drop(&mut self) { - println!("A"); - } -} +extern crate minicore; +use minicore::*; extern "C" { #[link_name = "llvm.sqrt.f32"] @@ -19,12 +22,9 @@ extern "C" { } pub fn do_call() { - let _a = A; - unsafe { // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them - // CHECK: store float 4.000000e+00, ptr %{{.}}, align 4 - // CHECK: call float @llvm.sqrt.f32(float %{{.}} + // CHECK: call float @llvm.sqrt.f32(float 4.000000e+00) sqrt(4.0); } } From 083b5db4766dc02e939e3aa92182dbad37d05b4b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 3 Mar 2026 14:06:03 +1100 Subject: [PATCH 35/35] Make `rustc_with_all_queries!` pass query modifiers as named values --- compiler/rustc_macros/src/query.rs | 155 ++++++------ .../rustc_middle/src/dep_graph/dep_node.rs | 6 +- compiler/rustc_middle/src/query/plumbing.rs | 212 +++++++--------- .../rustc_query_impl/src/dep_kind_vtables.rs | 22 +- compiler/rustc_query_impl/src/plumbing.rs | 237 ++++++------------ 5 files changed, 260 insertions(+), 372 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 721cc7fe4d9b3..0a741d32ed61d 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -137,54 +137,23 @@ struct CacheOnDiskIf { block: Block, } +/// See `rustc_middle::query::modifiers` for documentation of each query modifier. struct QueryModifiers { - /// The description of the query. - desc: Desc, - - /// Use this type for the in-memory cache. + // tidy-alphabetical-start + anon: Option, arena_cache: Option, - - /// Cache the query to disk if the `Block` returns true. cache_on_disk_if: Option, - - /// A cycle error for this query aborting the compilation with a fatal error. - cycle_fatal: Option, - - /// A cycle error results in a delay_bug call cycle_delay_bug: Option, - - /// A cycle error results in a stashed cycle error that can be unstashed and canceled later + cycle_fatal: Option, cycle_stash: Option, - - /// Don't hash the result, instead just mark a query red if it runs - no_hash: Option, - - /// Generate a dep node based on the dependencies of the query - anon: Option, - - /// Always evaluate the query, ignoring its dependencies - eval_always: Option, - - /// Whether the query has a call depth limit depth_limit: Option, - - /// Use a separate query provider for local and extern crates - separate_provide_extern: Option, - - /// Generate a `feed` method to set the query's value from another query. + desc: Desc, + eval_always: Option, feedable: Option, - - /// When this query is called via `tcx.ensure_ok()`, it returns - /// `Result<(), ErrorGuaranteed>` instead of `()`. If the query needs to - /// be executed, and that execution returns an error, the error result is - /// returned to the caller. - /// - /// If execution is skipped, a synthetic `Ok(())` is returned, on the - /// assumption that a query with all-green inputs must have succeeded. - /// - /// Can only be applied to queries with a return value of - /// `Result<_, ErrorGuaranteed>`. + no_hash: Option, return_result_from_ensure_ok: Option, + separate_provide_extern: Option, + // tidy-alphabetical-end } fn parse_query_modifiers(input: ParseStream<'_>) -> Result { @@ -272,6 +241,68 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { }) } +fn make_modifiers_stream(query: &Query, modifiers: &QueryModifiers) -> proc_macro2::TokenStream { + let QueryModifiers { + // tidy-alphabetical-start + anon, + arena_cache, + cache_on_disk_if, + cycle_delay_bug, + cycle_fatal, + cycle_stash, + depth_limit, + desc: _, + eval_always, + feedable, + no_hash, + return_result_from_ensure_ok, + separate_provide_extern, + // tidy-alphabetical-end + } = modifiers; + + let anon = anon.is_some(); + let arena_cache = arena_cache.is_some(); + let cache_on_disk = cache_on_disk_if.is_some(); + + let cycle_error_handling = if cycle_delay_bug.is_some() { + quote! { DelayBug } + } else if cycle_fatal.is_some() { + quote! { Fatal } + } else if cycle_stash.is_some() { + quote! { Stash } + } else { + quote! { Error } + }; + + let depth_limit = depth_limit.is_some(); + let eval_always = eval_always.is_some(); + let feedable = feedable.is_some(); + let no_hash = no_hash.is_some(); + let return_result_from_ensure_ok = return_result_from_ensure_ok.is_some(); + let separate_provide_extern = separate_provide_extern.is_some(); + + // Giving an input span to the modifier names in the modifier list seems + // to give slightly more helpful errors when one of the callback macros + // fails to parse the modifier list. + let query_name_span = query.name.span(); + quote_spanned! { + query_name_span => + // Search for (QMODLIST) to find all occurrences of this query modifier list. + // tidy-alphabetical-start + anon: #anon, + arena_cache: #arena_cache, + cache_on_disk: #cache_on_disk, + cycle_error_handling: #cycle_error_handling, + depth_limit: #depth_limit, + eval_always: #eval_always, + feedable: #feedable, + no_hash: #no_hash, + return_result_from_ensure_ok: #return_result_from_ensure_ok, + separate_provide_extern: #separate_provide_extern, + // tidy-alphabetical-end + } +} + fn doc_comment_from_desc(list: &Punctuated) -> Result { use ::syn::*; let mut iter = list.iter(); @@ -458,51 +489,13 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { ReturnType::Type(..) => quote! { #return_ty }, }; - let mut modifiers_out = vec![]; - - macro_rules! passthrough { - ( $( $modifier:ident ),+ $(,)? ) => { - $( if let Some($modifier) = &modifiers.$modifier { - modifiers_out.push(quote! { (#$modifier) }); - }; )+ - } - } - - passthrough!( - arena_cache, - cycle_fatal, - cycle_delay_bug, - cycle_stash, - no_hash, - anon, - eval_always, - feedable, - depth_limit, - separate_provide_extern, - return_result_from_ensure_ok, - ); - - // If there was a `cache_on_disk_if` modifier in the real input, pass - // on a synthetic `(cache_on_disk)` modifier that can be inspected by - // macro-rules macros. - if modifiers.cache_on_disk_if.is_some() { - modifiers_out.push(quote! { (cache_on_disk) }); - } - - // This uses the span of the query definition for the commas, - // which can be important if we later encounter any ambiguity - // errors with any of the numerous macro_rules! macros that - // we use. Using the call-site span would result in a span pointing - // at the entire `rustc_queries!` invocation, which wouldn't - // be very useful. - let span = name.span(); - let modifiers_stream = quote_spanned! { span => #(#modifiers_out),* }; + let modifiers_stream = make_modifiers_stream(&query, modifiers); // Add the query to the group query_stream.extend(quote! { #(#doc_comments)* - [#modifiers_stream] - fn #name(#key_ty) #return_ty, + fn #name(#key_ty) #return_ty + { #modifiers_stream } }); if let Some(feedable) = &modifiers.feedable { diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 7efa013c3d999..6f85dba23dd49 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -268,8 +268,10 @@ macro_rules! define_dep_nodes { queries { $( $(#[$q_attr:meta])* - [$($modifiers:tt)*] - fn $q_name:ident($K:ty) -> $V:ty, + fn $q_name:ident($K:ty) -> $V:ty + // Search for (QMODLIST) to find all occurrences of this query modifier list. + // Query modifiers are currently not used here, so skip the whole list. + { $($modifiers:tt)* } )* } non_queries { diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index ff6d87298028f..815c8a1baab61 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -333,44 +333,6 @@ macro_rules! query_helper_param_ty { ($K:ty) => { $K }; } -// Expands to `$yes` if the `arena_cache` modifier is present, `$no` otherwise. -macro_rules! if_arena_cache { - ([] $then:tt $no:tt) => { $no }; - ([(arena_cache) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_arena_cache!([$($modifiers)*] $yes $no) - }; -} - -// Expands to `$yes` if the `separate_provide_extern` modifier is present, `$no` otherwise. -macro_rules! if_separate_provide_extern { - ([] $then:tt $no:tt) => { $no }; - ([(separate_provide_extern) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_separate_provide_extern!([$($modifiers)*] $yes $no) - }; -} - -// Expands to `$yes` if the `return_result_from_ensure_ok` modifier is present, `$no` otherwise. -macro_rules! if_return_result_from_ensure_ok { - ([] $then:tt $no:tt) => { $no }; - ([(return_result_from_ensure_ok) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_return_result_from_ensure_ok!([$($modifiers)*] $yes $no) - }; -} - -// Expands to `$item` if the `feedable` modifier is present. -macro_rules! item_if_feedable { - ([] $($item:tt)*) => {}; - ([(feedable) $($rest:tt)*] $($item:tt)*) => { - $($item)* - }; - ([$other:tt $($modifiers:tt)*] $($item:tt)*) => { - item_if_feedable! { [$($modifiers)*] $($item)* } - }; -} - macro_rules! define_callbacks { ( // You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that @@ -378,8 +340,20 @@ macro_rules! define_callbacks { queries { $( $(#[$attr:meta])* - [$($modifiers:tt)*] - fn $name:ident($($K:tt)*) -> $V:ty, + fn $name:ident($($K:tt)*) -> $V:ty + { + // Search for (QMODLIST) to find all occurrences of this query modifier list. + anon: $anon:literal, + arena_cache: $arena_cache:literal, + cache_on_disk: $cache_on_disk:literal, + cycle_error_handling: $cycle_error_handling:ident, + depth_limit: $depth_limit:literal, + eval_always: $eval_always:literal, + feedable: $feedable:literal, + no_hash: $no_hash:literal, + return_result_from_ensure_ok: $return_result_from_ensure_ok:literal, + separate_provide_extern: $separate_provide_extern:literal, + } )* } // Non-queries are unused here. @@ -394,20 +368,31 @@ macro_rules! define_callbacks { pub type Key<'tcx> = $($K)*; pub type Value<'tcx> = $V; - pub type LocalKey<'tcx> = if_separate_provide_extern!( - [$($modifiers)*] - ( as $crate::query::AsLocalQueryKey>::LocalQueryKey) - (Key<'tcx>) - ); - - /// This type alias specifies the type returned from query providers and the type - /// used for decoding. For regular queries this is the declared returned type `V`, - /// but `arena_cache` will use `::Provided` instead. - pub type ProvidedValue<'tcx> = if_arena_cache!( - [$($modifiers)*] - ( as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) - (Value<'tcx>) - ); + /// Key type used by provider functions in `local_providers`. + /// This query has the `separate_provide_extern` modifier. + #[cfg($separate_provide_extern)] + pub type LocalKey<'tcx> = + as $crate::query::AsLocalQueryKey>::LocalQueryKey; + /// Key type used by provider functions in `local_providers`. + #[cfg(not($separate_provide_extern))] + pub type LocalKey<'tcx> = Key<'tcx>; + + /// Return type of the `.ensure_ok()` method for this query, + /// which has the `return_result_from_ensure_ok` modifier. + #[cfg($return_result_from_ensure_ok)] + pub type EnsureOkReturnType = Result<(), rustc_errors::ErrorGuaranteed>; + /// Return type of the `.ensure_ok()` method for this query, + /// which does _not_ have the `return_result_from_ensure_ok` modifier. + #[cfg(not($return_result_from_ensure_ok))] + pub type EnsureOkReturnType = (); + + /// Type returned from query providers and loaded from disk-cache. + #[cfg($arena_cache)] + pub type ProvidedValue<'tcx> = + as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided; + /// Type returned from query providers and loaded from disk-cache. + #[cfg(not($arena_cache))] + pub type ProvidedValue<'tcx> = Value<'tcx>; /// This helper function takes a value returned by the query provider /// (or loaded from disk, or supplied by query feeding), allocates @@ -420,23 +405,23 @@ macro_rules! define_callbacks { ) -> Erased> { // For queries with the `arena_cache` modifier, store the // provided value in an arena and get a reference to it. - let value: Value<'tcx> = if_arena_cache!( - [$($modifiers)*] - { - as $crate::query::arena_cached::ArenaCached>:: - alloc_in_arena - ( - tcx, - &tcx.query_system.arenas.$name, - provided_value, - ) - } - { - // Otherwise, the provided value is the value (and `tcx` is unused). - let _ = tcx; - provided_value - } - ); + #[cfg($arena_cache)] + let value: Value<'tcx> = { + use $crate::query::arena_cached::ArenaCached; + as ArenaCached>::alloc_in_arena( + tcx, + &tcx.query_system.arenas.$name, + provided_value, + ) + }; + + // Otherwise, the provided value is the value (and `tcx` is unused). + #[cfg(not($arena_cache))] + let value: Value<'tcx> = { + let _ = tcx; + provided_value + }; + erase::erase_val(value) } @@ -480,13 +465,11 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryArenas<'tcx> { $( - pub $name: if_arena_cache!( - [$($modifiers)*] - // Use the `ArenaCached` helper trait to determine the arena's value type. - (TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>) - // No arena for this query, so the field type is `()`. - () - ), + // Use the `ArenaCached` helper trait to determine the arena's value type. + #[cfg($arena_cache)] + pub $name: TypedArena< + <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated, + >, )* } @@ -497,16 +480,14 @@ macro_rules! define_callbacks { pub fn $name( self, key: query_helper_param_ty!($($K)*), - ) -> if_return_result_from_ensure_ok!( - [$($modifiers)*] - (Result<(), ErrorGuaranteed>) - () - ) { - if_return_result_from_ensure_ok!( - [$($modifiers)*] - (crate::query::inner::query_ensure_error_guaranteed) - (crate::query::inner::query_ensure) - )( + ) -> $crate::queries::$name::EnsureOkReturnType { + + #[cfg($return_result_from_ensure_ok)] + let ensure_fn = crate::query::inner::query_ensure_error_guaranteed; + #[cfg(not($return_result_from_ensure_ok))] + let ensure_fn = crate::query::inner::query_ensure; + + ensure_fn( self.tcx, &self.tcx.query_system.query_vtables.$name, $crate::query::IntoQueryParam::into_query_param(key), @@ -560,24 +541,22 @@ macro_rules! define_callbacks { } $( - item_if_feedable! { - [$($modifiers)*] - impl<'tcx, K: $crate::query::IntoQueryParam<$name::Key<'tcx>> + Copy> - TyCtxtFeed<'tcx, K> - { - $(#[$attr])* - #[inline(always)] - pub fn $name(self, value: $name::ProvidedValue<'tcx>) { - let key = self.key().into_query_param(); - let erased_value = $name::provided_to_erased(self.tcx, value); - $crate::query::inner::query_feed( - self.tcx, - dep_graph::DepKind::$name, - &self.tcx.query_system.query_vtables.$name, - key, - erased_value, - ); - } + #[cfg($feedable)] + impl<'tcx, K: $crate::query::IntoQueryParam<$name::Key<'tcx>> + Copy> + TyCtxtFeed<'tcx, K> + { + $(#[$attr])* + #[inline(always)] + pub fn $name(self, value: $name::ProvidedValue<'tcx>) { + let key = self.key().into_query_param(); + let erased_value = $name::provided_to_erased(self.tcx, value); + $crate::query::inner::query_feed( + self.tcx, + dep_graph::DepKind::$name, + &self.tcx.query_system.query_vtables.$name, + key, + erased_value, + ); } } )* @@ -602,11 +581,11 @@ macro_rules! define_callbacks { pub struct ExternProviders { $( - pub $name: if_separate_provide_extern!( - [$($modifiers)*] - (for<'tcx> fn(TyCtxt<'tcx>, $name::Key<'tcx>) -> $name::ProvidedValue<'tcx>) - () - ), + #[cfg($separate_provide_extern)] + pub $name: for<'tcx> fn( + TyCtxt<'tcx>, + $name::Key<'tcx>, + ) -> $name::ProvidedValue<'tcx>, )* } @@ -626,13 +605,10 @@ macro_rules! define_callbacks { fn default() -> Self { ExternProviders { $( - $name: if_separate_provide_extern!( - [$($modifiers)*] - (|_, key| $crate::query::plumbing::default_extern_query( - stringify!($name), - &key - )) - () + #[cfg($separate_provide_extern)] + $name: |_, key| $crate::query::plumbing::default_extern_query( + stringify!($name), + &key, ), )* } diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs index ceddef5385a58..0f3ef34d936a4 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -130,8 +130,20 @@ macro_rules! define_dep_kind_vtables { queries { $( $(#[$attr:meta])* - [$($modifiers:tt)*] - fn $name:ident($K:ty) -> $V:ty, + fn $name:ident($K:ty) -> $V:ty + { + // Search for (QMODLIST) to find all occurrences of this query modifier list. + anon: $anon:literal, + arena_cache: $arena_cache:literal, + cache_on_disk: $cache_on_disk:literal, + cycle_error_handling: $cycle_error_handling:ident, + depth_limit: $depth_limit:literal, + eval_always: $eval_always:literal, + feedable: $feedable:literal, + no_hash: $no_hash:literal, + return_result_from_ensure_ok: $return_result_from_ensure_ok:literal, + separate_provide_extern: $separate_provide_extern:literal, + } )* } non_queries { @@ -154,9 +166,9 @@ macro_rules! define_dep_kind_vtables { $crate::dep_kind_vtables::make_dep_kind_vtable_for_query::< $crate::query_impl::$name::VTableGetter, >( - is_anon!([$($modifiers)*]), - if_cache_on_disk!([$($modifiers)*] true false), - is_eval_always!([$($modifiers)*]), + $anon, + $cache_on_disk, + $eval_always, ) ),* ]; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 17e6fba8ac9a5..425ca28910073 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -99,125 +99,6 @@ pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> boo tcx.dep_graph.try_mark_green(tcx, dep_node).is_some() } -macro_rules! cycle_error_handling { - ([]) => {{ - rustc_middle::query::CycleErrorHandling::Error - }}; - ([(cycle_fatal) $($rest:tt)*]) => {{ - rustc_middle::query::CycleErrorHandling::Fatal - }}; - ([(cycle_stash) $($rest:tt)*]) => {{ - rustc_middle::query::CycleErrorHandling::Stash - }}; - ([(cycle_delay_bug) $($rest:tt)*]) => {{ - rustc_middle::query::CycleErrorHandling::DelayBug - }}; - ([$other:tt $($modifiers:tt)*]) => { - cycle_error_handling!([$($modifiers)*]) - }; -} - -macro_rules! is_anon { - ([]) => {{ - false - }}; - ([(anon) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_anon!([$($modifiers)*]) - }; -} - -macro_rules! is_eval_always { - ([]) => {{ - false - }}; - ([(eval_always) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_eval_always!([$($modifiers)*]) - }; -} - -macro_rules! is_depth_limit { - ([]) => {{ - false - }}; - ([(depth_limit) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_depth_limit!([$($modifiers)*]) - }; -} - -macro_rules! is_feedable { - ([]) => {{ - false - }}; - ([(feedable) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_feedable!([$($modifiers)*]) - }; -} - -/// Expands to `$yes` if the `no_hash` modifier is present, or `$no` otherwise. -macro_rules! if_no_hash { - ([] $yes:tt $no:tt) => { $no }; - ([(no_hash) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_no_hash!([$($modifiers)*] $yes $no) - } -} - -macro_rules! call_provider { - ([][$tcx:expr, $name:ident, $key:expr]) => {{ - ($tcx.query_system.local_providers.$name)($tcx, $key) - }}; - ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{ - if let Some(key) = $key.as_local_key() { - ($tcx.query_system.local_providers.$name)($tcx, key) - } else { - ($tcx.query_system.extern_providers.$name)($tcx, $key) - } - }}; - ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { - call_provider!([$($modifiers)*][$($args)*]) - }; -} - -/// Expands to one of two token trees, depending on whether the current query -/// has the `cache_on_disk_if` modifier. -macro_rules! if_cache_on_disk { - ([] $yes:tt $no:tt) => { - $no - }; - // The `cache_on_disk_if` modifier generates a synthetic `(cache_on_disk)`, - // modifier, for use by this macro and similar macros. - ([(cache_on_disk) $($rest:tt)*] $yes:tt $no:tt) => { - $yes - }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_cache_on_disk!([$($modifiers)*] $yes $no) - }; -} - -/// Conditionally expands to some token trees, if the current query has the -/// `cache_on_disk_if` modifier. -macro_rules! item_if_cache_on_disk { - ([] $($item:tt)*) => {}; - ([(cache_on_disk) $($rest:tt)*] $($item:tt)*) => { - $($item)* - }; - ([$other:tt $($modifiers:tt)*] $($item:tt)*) => { - item_if_cache_on_disk! { [$($modifiers)*] $($item)* } - }; -} - /// The deferred part of a deferred query stack frame. fn mk_query_stack_frame_extra<'tcx, Cache>( (tcx, vtable, key): (TyCtxt<'tcx>, &'tcx QueryVTable<'tcx, Cache>, Cache::Key), @@ -421,8 +302,20 @@ macro_rules! define_queries { queries { $( $(#[$attr:meta])* - [$($modifiers:tt)*] - fn $name:ident($K:ty) -> $V:ty, + fn $name:ident($K:ty) -> $V:ty + { + // Search for (QMODLIST) to find all occurrences of this query modifier list. + anon: $anon:literal, + arena_cache: $arena_cache:literal, + cache_on_disk: $cache_on_disk:literal, + cycle_error_handling: $cycle_error_handling:ident, + depth_limit: $depth_limit:literal, + eval_always: $eval_always:literal, + feedable: $feedable:literal, + no_hash: $no_hash:literal, + return_result_from_ensure_ok: $return_result_from_ensure_ok:literal, + separate_provide_extern: $separate_provide_extern:literal, + } )* } // Non-queries are unused here. @@ -498,7 +391,16 @@ macro_rules! define_queries { let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); // Call the actual provider function for this query. - let provided_value = call_provider!([$($modifiers)*][tcx, $name, key]); + + #[cfg($separate_provide_extern)] + let provided_value = if let Some(local_key) = key.as_local_key() { + (tcx.query_system.local_providers.$name)(tcx, local_key) + } else { + (tcx.query_system.extern_providers.$name)(tcx, key) + }; + + #[cfg(not($separate_provide_extern))] + let provided_value = (tcx.query_system.local_providers.$name)(tcx, key); rustc_middle::ty::print::with_reduced_queries!({ tracing::trace!(?provided_value); @@ -515,64 +417,67 @@ macro_rules! define_queries { { QueryVTable { name: stringify!($name), - anon: is_anon!([$($modifiers)*]), - eval_always: is_eval_always!([$($modifiers)*]), - depth_limit: is_depth_limit!([$($modifiers)*]), - feedable: is_feedable!([$($modifiers)*]), + anon: $anon, + eval_always: $eval_always, + depth_limit: $depth_limit, + feedable: $feedable, dep_kind: dep_graph::DepKind::$name, - cycle_error_handling: cycle_error_handling!([$($modifiers)*]), + cycle_error_handling: + rustc_middle::query::CycleErrorHandling::$cycle_error_handling, state: Default::default(), cache: Default::default(), - will_cache_on_disk_for_key_fn: if_cache_on_disk!([$($modifiers)*] { - Some(::rustc_middle::queries::_cache_on_disk_if_fns::$name) - } { - None - }), + + #[cfg($cache_on_disk)] + will_cache_on_disk_for_key_fn: + Some(rustc_middle::queries::_cache_on_disk_if_fns::$name), + #[cfg(not($cache_on_disk))] + will_cache_on_disk_for_key_fn: None, + call_query_method_fn: |tcx, key| { // Call the query method for its side-effect of loading a value // from disk-cache; the caller doesn't need the value. let _ = tcx.$name(key); }, invoke_provider_fn: self::invoke_provider_fn::__rust_begin_short_backtrace, - try_load_from_disk_fn: if_cache_on_disk!([$($modifiers)*] { - Some(|tcx, key, prev_index, index| { - // Check the `cache_on_disk_if` condition for this key. - if !::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) { - return None; - } - - let value: queries::$name::ProvidedValue<'tcx> = - $crate::plumbing::try_load_from_disk(tcx, prev_index, index)?; - - // Arena-alloc the value if appropriate, and erase it. - Some(queries::$name::provided_to_erased(tcx, value)) - }) - } { - None + + #[cfg($cache_on_disk)] + try_load_from_disk_fn: Some(|tcx, key, prev_index, index| { + // Check the `cache_on_disk_if` condition for this key. + if !rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) { + return None; + } + + let value: queries::$name::ProvidedValue<'tcx> = + $crate::plumbing::try_load_from_disk(tcx, prev_index, index)?; + + // Arena-alloc the value if appropriate, and erase it. + Some(queries::$name::provided_to_erased(tcx, value)) }), - is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] { - Some(|tcx, key, index| -> bool { - ::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) && - $crate::plumbing::loadable_from_disk(tcx, index) - }) - } { - None + #[cfg(not($cache_on_disk))] + try_load_from_disk_fn: None, + + #[cfg($cache_on_disk)] + is_loadable_from_disk_fn: Some(|tcx, key, index| -> bool { + rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) && + $crate::plumbing::loadable_from_disk(tcx, index) }), + #[cfg(not($cache_on_disk))] + is_loadable_from_disk_fn: None, + value_from_cycle_error: |tcx, cycle, guar| { let result: queries::$name::Value<'tcx> = FromCycleError::from_cycle_error(tcx, cycle, guar); erase::erase_val(result) }, - hash_value_fn: if_no_hash!( - [$($modifiers)*] - None - { - Some(|hcx, erased_value: &erase::Erased>| { - let value = erase::restore_val(*erased_value); - rustc_middle::dep_graph::hash_result(hcx, &value) - }) - } - ), + + #[cfg($no_hash)] + hash_value_fn: None, + #[cfg(not($no_hash))] + hash_value_fn: Some(|hcx, erased_value: &erase::Erased>| { + let value = erase::restore_val(*erased_value); + rustc_middle::dep_graph::hash_result(hcx, &value) + }), + format_value: |value| format!("{:?}", erase::restore_val::>(*value)), description_fn: $crate::queries::_description_fns::$name, execute_query_fn: if incremental { @@ -670,8 +575,8 @@ macro_rules! define_queries { query_result_index: &mut EncodedDepNodeIndex, ) { $( - item_if_cache_on_disk! { - [$($modifiers)*] + #[cfg($cache_on_disk)] + { $crate::plumbing::encode_query_results( tcx, &tcx.query_system.query_vtables.$name,