Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl Layout {
pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
if Layout::is_size_align_valid(size, align) {
// SAFETY: Layout::is_size_align_valid checks the preconditions for this call.
unsafe { Ok(Layout { size, align: mem::transmute(align) }) }
unsafe { Ok(Layout { size, align: mem::transmute::<usize, Alignment>(align) }) }
} else {
Err(LayoutError)
}
Expand Down Expand Up @@ -140,7 +140,7 @@ impl Layout {
) => Layout::is_size_align_valid(size, align)
);
// SAFETY: the caller is required to uphold the preconditions.
unsafe { Layout { size, align: mem::transmute(align) } }
unsafe { Layout { size, align: mem::transmute::<usize, Alignment>(align) } }
}

/// Creates a layout, bypassing all checks.
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/array/equality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const impl<T: [const] BytewiseEq<U>, U, const N: usize> SpecArrayEq<U, N> for T
// SAFETY: Arrays are compared element-wise, and don't add any padding
// between elements, so when the elements are `BytewiseEq`, we can
// compare the entire array at once.
unsafe { crate::intrinsics::raw_eq(a, crate::mem::transmute(b)) }
unsafe { crate::intrinsics::raw_eq(a, crate::mem::transmute::<&[U; N], &[T; N]>(b)) }
}
fn spec_ne(a: &[T; N], b: &[U; N]) -> bool {
!Self::spec_eq(a, b)
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/char/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> {
Err(CharTryFromError(()))
} else {
// SAFETY: checked that it's a legal unicode value
Ok(unsafe { transmute(i) })
Ok(unsafe { transmute::<u32, char>(i) })
}
}

Expand Down
11 changes: 8 additions & 3 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,12 @@ impl<'a> Arguments<'a> {
args: &'a [rt::Argument<'a>; M],
) -> Arguments<'a> {
// SAFETY: Responsibility of the caller.
unsafe { Arguments { template: mem::transmute(template), args: mem::transmute(args) } }
unsafe {
Arguments {
template: mem::transmute::<&[u8; N], NonNull<u8>>(template),
args: mem::transmute::<&[rt::Argument<'_>; M], NonNull<rt::Argument<'_>>>(args),
}
}
}

// Same as `from_str`, but not const.
Expand Down Expand Up @@ -816,8 +821,8 @@ impl<'a> Arguments<'a> {
// SAFETY: This is the "static str" representation of fmt::Arguments; see above.
unsafe {
Arguments {
template: mem::transmute(s.as_ptr()),
args: mem::transmute(s.len() << 1 | 1),
template: mem::transmute::<*const u8, NonNull<u8>>(s.as_ptr()),
args: mem::transmute::<usize, NonNull<rt::Argument<'_>>>(s.len() << 1 | 1),
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion library/core/src/fmt/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,14 @@ macro_rules! argument_new {
#[cfg(not(any(sanitize = "cfi", sanitize = "kcfi")))]
formatter: {
let f: fn(&$t, &mut Formatter<'_>) -> Result = $f;
#[expect(
clippy::missing_transmute_annotations,
reason = "inside macro, types are unknown or too complex"
)]
// SAFETY: This is only called with `value`, which has the right type.
unsafe { core::mem::transmute(f) }
unsafe {
core::mem::transmute(f)
}
},
#[cfg(any(sanitize = "cfi", sanitize = "kcfi"))]
formatter: |ptr: NonNull<()>, fmt: &mut Formatter<'_>| {
Expand Down
5 changes: 4 additions & 1 deletion library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3130,7 +3130,10 @@ pub fn type_id<T: ?Sized>() -> crate::any::TypeId;
pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool {
// SAFETY: we know `TypeId` is 16 bytes of initialized data.
// This is runtime-only code so we do not have to worry about provenance.
unsafe { crate::mem::transmute::<_, u128>(a) == crate::mem::transmute::<_, u128>(b) }
unsafe {
crate::mem::transmute::<crate::any::TypeId, u128>(a)
== crate::mem::transmute::<crate::any::TypeId, u128>(b)

@RalfJung RalfJung Aug 24, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I am not sure this makes the code better. The type of a and b is right there in the function signature, what is the point in repeating it?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe
a) we could add an expect/allow instead.
b) the lint should not fire in this case. Right now, the lint does not fire if the transmute is the only element in the function, which is not the case here, it is a bit more complex.

}
}

/// Returns whether the type represented by this `TypeId` is a signed integer.
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/net/ip_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,7 @@ impl Ipv6Addr {
Ipv6Addr {
// All elements in `addr16` are big endian.
// SAFETY: `[u16; 8]` is always safe to transmute to `[u8; 16]`.
octets: unsafe { transmute::<_, [u8; 16]>(addr16) },
octets: unsafe { transmute::<[u16; 8], [u8; 16]>(addr16) },
}
}

Expand Down Expand Up @@ -1525,7 +1525,7 @@ impl Ipv6Addr {
pub const fn segments(&self) -> [u16; 8] {
// All elements in `self.octets` must be big endian.
// SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`.
let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.octets) };
let [a, b, c, d, e, f, g, h] = unsafe { transmute::<[u8; 16], [u16; 8]>(self.octets) };
// We want native endian u16
[
u16::from_be(a),
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/num/niche_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ macro_rules! define_valid_range_type {
#[allow(non_contiguous_range_endpoints)]
if let $pat = val {
// SAFETY: just checked that the value matches the pattern
Some(unsafe { $name(crate::mem::transmute(val)) })
Some(unsafe { $name(crate::mem::transmute::<$int, pattern_type!($int is $pat)>(val)) })
} else {
None
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/task/wake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ impl<'a> ContextBuilder<'a> {
#[unstable(feature = "local_waker", issue = "118959")]
pub const fn from_waker(waker: &'a Waker) -> Self {
// SAFETY: LocalWaker is just Waker without thread safety
let local_waker = unsafe { transmute(waker) };
let local_waker = unsafe { transmute::<&Waker, &LocalWaker>(waker) };
Self {
waker,
local_waker,
Expand Down
13 changes: 10 additions & 3 deletions library/std/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,11 @@ pub fn set_alloc_error_hook(hook: fn(Layout)) {
#[unstable(feature = "alloc_error_hook", issue = "51245")]
pub fn take_alloc_error_hook() -> fn(Layout) {
let hook = HOOK.swap(ptr::null_mut(), Ordering::Acquire);
if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } }
if hook.is_null() {
default_alloc_error_hook
} else {
unsafe { mem::transmute::<*mut (), fn(core::alloc::Layout)>(hook) }
}
}

#[optimize(size)]
Expand Down Expand Up @@ -435,8 +439,11 @@ fn default_alloc_error_hook(layout: Layout) {
pub fn rust_oom(layout: Layout) -> ! {
crate::sys::backtrace::__rust_end_short_backtrace(|| {
let hook = HOOK.load(Ordering::Acquire);
let hook: fn(Layout) =
if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } };
let hook: fn(Layout) = if hook.is_null() {
default_alloc_error_hook
} else {
unsafe { mem::transmute::<*mut (), fn(core::alloc::Layout)>(hook) }
};
hook(layout);
crate::process::abort()
})
Expand Down
11 changes: 10 additions & 1 deletion library/std/src/sys/thread_local/key/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,16 @@ pub type Key = libc::pthread_key_t;
#[inline]
pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
let mut key = 0;
if unsafe { libc::pthread_key_create(&mut key, mem::transmute(dtor)) } != 0 {
if unsafe {
libc::pthread_key_create(
&mut key,
mem::transmute::<
core::option::Option<unsafe extern "C" fn(*mut u8)>,
core::option::Option<unsafe extern "C" fn(*mut libc::c_void)>,
>(dtor),
)
} != 0
{
rtabort!("out of TLS keys");
}
key
Expand Down
16 changes: 8 additions & 8 deletions library/stdarch/crates/core_arch/src/x86/avx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ pub const fn _mm256_blend_ps<const IMM8: i32>(a: __m256, b: __m256) -> __m256 {
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
pub const fn _mm256_blendv_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d {
unsafe {
let mask: i64x4 = simd_lt(transmute::<_, i64x4>(c), i64x4::ZERO);
let mask: i64x4 = simd_lt(transmute::<__m256d, i64x4>(c), i64x4::ZERO);
transmute(simd_select(mask, b.as_f64x4(), a.as_f64x4()))
}
}
Expand All @@ -581,7 +581,7 @@ pub const fn _mm256_blendv_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d {
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
pub const fn _mm256_blendv_ps(a: __m256, b: __m256, c: __m256) -> __m256 {
unsafe {
let mask: i32x8 = simd_lt(transmute::<_, i32x8>(c), i32x8::ZERO);
let mask: i32x8 = simd_lt(transmute::<__m256, i32x8>(c), i32x8::ZERO);
transmute(simd_select(mask, b.as_f32x8(), a.as_f32x8()))
}
}
Expand Down Expand Up @@ -2195,7 +2195,7 @@ pub fn _mm256_testnzc_pd(a: __m256d, b: __m256d) -> i32 {
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
pub const fn _mm_testz_pd(a: __m128d, b: __m128d) -> i32 {
unsafe {
let r: i64x2 = simd_lt(transmute(_mm_and_pd(a, b)), i64x2::ZERO);
let r: i64x2 = simd_lt(transmute::<__m128d, i64x2>(_mm_and_pd(a, b)), i64x2::ZERO);
(0i64 == simd_reduce_or(r)) as i32
}
}
Expand All @@ -2216,7 +2216,7 @@ pub const fn _mm_testz_pd(a: __m128d, b: __m128d) -> i32 {
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
pub const fn _mm_testc_pd(a: __m128d, b: __m128d) -> i32 {
unsafe {
let r: i64x2 = simd_lt(transmute(_mm_andnot_pd(a, b)), i64x2::ZERO);
let r: i64x2 = simd_lt(transmute::<__m128d, i64x2>(_mm_andnot_pd(a, b)), i64x2::ZERO);
(0i64 == simd_reduce_or(r)) as i32
}
}
Expand Down Expand Up @@ -2307,7 +2307,7 @@ pub fn _mm256_testnzc_ps(a: __m256, b: __m256) -> i32 {
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
pub const fn _mm_testz_ps(a: __m128, b: __m128) -> i32 {
unsafe {
let r: i32x4 = simd_lt(transmute(_mm_and_ps(a, b)), i32x4::ZERO);
let r: i32x4 = simd_lt(transmute::<__m128, i32x4>(_mm_and_ps(a, b)), i32x4::ZERO);
(0i32 == simd_reduce_or(r)) as i32
}
}
Expand All @@ -2328,7 +2328,7 @@ pub const fn _mm_testz_ps(a: __m128, b: __m128) -> i32 {
#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
pub const fn _mm_testc_ps(a: __m128, b: __m128) -> i32 {
unsafe {
let r: i32x4 = simd_lt(transmute(_mm_andnot_ps(a, b)), i32x4::ZERO);
let r: i32x4 = simd_lt(transmute::<__m128, i32x4>(_mm_andnot_ps(a, b)), i32x4::ZERO);
(0i32 == simd_reduce_or(r)) as i32
}
}
Expand Down Expand Up @@ -2365,7 +2365,7 @@ pub const fn _mm256_movemask_pd(a: __m256d) -> i32 {
// Propagate the highest bit to the rest, because simd_bitmask
// requires all-1 or all-0.
unsafe {
let mask: i64x4 = simd_lt(transmute(a), i64x4::ZERO);
let mask: i64x4 = simd_lt(transmute::<__m256d, i64x4>(a), i64x4::ZERO);
simd_bitmask::<i64x4, u8>(mask) as i32
}
}
Expand All @@ -2384,7 +2384,7 @@ pub const fn _mm256_movemask_ps(a: __m256) -> i32 {
// Propagate the highest bit to the rest, because simd_bitmask
// requires all-1 or all-0.
unsafe {
let mask: i32x8 = simd_lt(transmute(a), i32x8::ZERO);
let mask: i32x8 = simd_lt(transmute::<__m256, i32x8>(a), i32x8::ZERO);
simd_bitmask::<i32x8, u8>(mask) as i32
}
}
Expand Down
16 changes: 8 additions & 8 deletions library/stdarch/crates/core_arch/src/x86/avx2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2738,7 +2738,7 @@ pub const fn _mm256_slli_epi16<const IMM8: i32>(a: __m256i) -> __m256i {
if IMM8 >= 16 {
_mm256_setzero_si256()
} else {
transmute(simd_shl(a.as_u16x16(), u16x16::splat(IMM8 as u16)))
transmute::<u16x16, __m256i>(simd_shl(a.as_u16x16(), u16x16::splat(IMM8 as u16)))
}
}
}
Expand All @@ -2759,7 +2759,7 @@ pub const fn _mm256_slli_epi32<const IMM8: i32>(a: __m256i) -> __m256i {
if IMM8 >= 32 {
_mm256_setzero_si256()
} else {
transmute(simd_shl(a.as_u32x8(), u32x8::splat(IMM8 as u32)))
transmute::<u32x8, __m256i>(simd_shl(a.as_u32x8(), u32x8::splat(IMM8 as u32)))
}
}
}
Expand All @@ -2780,7 +2780,7 @@ pub const fn _mm256_slli_epi64<const IMM8: i32>(a: __m256i) -> __m256i {
if IMM8 >= 64 {
_mm256_setzero_si256()
} else {
transmute(simd_shl(a.as_u64x4(), u64x4::splat(IMM8 as u64)))
transmute::<u64x4, __m256i>(simd_shl(a.as_u64x4(), u64x4::splat(IMM8 as u64)))
}
}
}
Expand Down Expand Up @@ -3005,7 +3005,7 @@ pub const fn _mm_srav_epi32(a: __m128i, count: __m128i) -> __m128i {
unsafe {
let count = count.as_u32x4();
let no_overflow: u32x4 = simd_lt(count, u32x4::splat(u32::BITS));
let count = simd_select(no_overflow, transmute(count), i32x4::splat(31));
let count = simd_select(no_overflow, transmute::<u32x4, i32x4>(count), i32x4::splat(31));
simd_shr(a.as_i32x4(), count).as_m128i()
}
}
Expand All @@ -3023,7 +3023,7 @@ pub const fn _mm256_srav_epi32(a: __m256i, count: __m256i) -> __m256i {
unsafe {
let count = count.as_u32x8();
let no_overflow: u32x8 = simd_lt(count, u32x8::splat(u32::BITS));
let count = simd_select(no_overflow, transmute(count), i32x8::splat(31));
let count = simd_select(no_overflow, transmute::<u32x8, i32x8>(count), i32x8::splat(31));
simd_shr(a.as_i32x8(), count).as_m256i()
}
}
Expand Down Expand Up @@ -3157,7 +3157,7 @@ pub const fn _mm256_srli_epi16<const IMM8: i32>(a: __m256i) -> __m256i {
if IMM8 >= 16 {
_mm256_setzero_si256()
} else {
transmute(simd_shr(a.as_u16x16(), u16x16::splat(IMM8 as u16)))
transmute::<u16x16, __m256i>(simd_shr(a.as_u16x16(), u16x16::splat(IMM8 as u16)))
}
}
}
Expand All @@ -3178,7 +3178,7 @@ pub const fn _mm256_srli_epi32<const IMM8: i32>(a: __m256i) -> __m256i {
if IMM8 >= 32 {
_mm256_setzero_si256()
} else {
transmute(simd_shr(a.as_u32x8(), u32x8::splat(IMM8 as u32)))
transmute::<u32x8, __m256i>(simd_shr(a.as_u32x8(), u32x8::splat(IMM8 as u32)))
}
}
}
Expand All @@ -3199,7 +3199,7 @@ pub const fn _mm256_srli_epi64<const IMM8: i32>(a: __m256i) -> __m256i {
if IMM8 >= 64 {
_mm256_setzero_si256()
} else {
transmute(simd_shr(a.as_u64x4(), u64x4::splat(IMM8 as u64)))
transmute::<u64x4, __m256i>(simd_shr(a.as_u64x4(), u64x4::splat(IMM8 as u64)))
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions library/stdarch/crates/core_arch/src/x86/avx512bf16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,10 @@ pub fn _mm512_maskz_dpbf16_ps(k: __mmask16, src: __m512, a: __m512bh, b: __m512b
#[target_feature(enable = "avx512bf16,avx512f")]
#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
pub fn _mm512_cvtpbh_ps(a: __m256bh) -> __m512 {
unsafe { _mm512_castsi512_ps(_mm512_slli_epi32::<16>(_mm512_cvtepi16_epi32(transmute(a)))) }
unsafe { _mm512_castsi512_ps(_mm512_slli_epi32::<16>(_mm512_cvtepi16_epi32(transmute::<__m256bh, __m256i>(a)))) }
}


/// Converts packed BF16 (16-bit) floating-point elements in a to packed single-precision (32-bit)
/// floating-point elements, and store the results in dst using writemask k (elements are copied
/// from src when the corresponding mask bit is not set).
Expand Down Expand Up @@ -426,7 +427,7 @@ pub fn _mm512_maskz_cvtpbh_ps(k: __mmask16, a: __m256bh) -> __m512 {
#[target_feature(enable = "avx512bf16,avx512vl")]
#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
pub fn _mm256_cvtpbh_ps(a: __m128bh) -> __m256 {
unsafe { _mm256_castsi256_ps(_mm256_slli_epi32::<16>(_mm256_cvtepi16_epi32(transmute(a)))) }
unsafe { _mm256_castsi256_ps(_mm256_slli_epi32::<16>(_mm256_cvtepi16_epi32(transmute::<__m128bh, __m128i>(a)))) }
}

/// Converts packed BF16 (16-bit) floating-point elements in a to packed single-precision (32-bit)
Expand Down Expand Up @@ -467,7 +468,7 @@ pub fn _mm256_maskz_cvtpbh_ps(k: __mmask8, a: __m128bh) -> __m256 {
#[target_feature(enable = "avx512bf16,avx512vl")]
#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
pub fn _mm_cvtpbh_ps(a: __m128bh) -> __m128 {
unsafe { _mm_castsi128_ps(_mm_slli_epi32::<16>(_mm_cvtepi16_epi32(transmute(a)))) }
unsafe { _mm_castsi128_ps(_mm_slli_epi32::<16>(_mm_cvtepi16_epi32(transmute::<__m128bh, __m128i>(a)))) }
}

/// Converts packed BF16 (16-bit) floating-point elements in a to single-precision (32-bit) floating-point
Expand Down
Loading
Loading