Description
Summary
cast_slice_from_raw_parts
only looks for problematic cases where there is a cast using as
. However, if you follow other advice from Clippy and/or other tools, those as
conversions will get rewritten to equivalent conversions that do not use as
. But as
isn't really the problem; the problem is the construction of a &mut [T]
slice when we only want a *mut [T]
. Indeed, the rust-lang/rust code that had the bug that motivated the lint uses a cast that could have been written like the convert_slice_from_raw_parts_return_value
example below; it just happened to have an unnecessary cast.
I think it would be hard to decide all the different types of conversion operations that should trigger the lint. However, I think at least the case of implicit conversions from reference to pointer should trigger it.
I include only examples for &mut T
as those are the ones that are actually problematic--it seems the &T
case for the lint is really only done for symmetry--but the analogous &T
cases have the same issue.
Lint Name
cast_slice_from_raw_parts
Reproducer
I tried this code:
#![no_std]
#![allow(dead_code)]
#![deny(clippy::cast_slice_from_raw_parts)]
fn convert_slice_from_raw_parts_return_value(slice: &mut [u8]) -> *mut [u8] {
let (ptr, len) = (slice.as_mut_ptr(), slice.len());
// Clippy notes cast_slice_from_raw_parts with this unnecessary cast:
// (unsafe { std::slice::from_raw_parts_mut(ptr, len) }) as *mut [u8]
// But not this equivalent:
unsafe { core::slice::from_raw_parts_mut(ptr, len) }
}
fn convert_slice_from_raw_parts_local() {
let slice: &mut [u8] = &mut [0];
let (ptr, len) = (slice.as_mut_ptr(), slice.len());
// Clippy notes cast_slice_from_raw_parts with this unnecessary cast:
// let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(ptr, len) } as *mut [u8];
// But not this equivalent:
let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(ptr, len) };
}
fn from_mut_slice_from_raw_parts_return_value(slice: &mut [u8]) -> *mut [u8] {
let (ptr, len) = (slice.as_mut_ptr(), slice.len());
// Clippy notes cast_slice_from_raw_parts with this unnecessary cast:
// (unsafe { core::slice::from_raw_parts_mut(ptr, len) }) as *mut [u8]
// But not this equivalent:
core::ptr::from_mut(unsafe { core::slice::from_raw_parts_mut(ptr, len) })
}
fn from_mut_slice_from_raw_parts_local() {
let slice: &mut [u8] = &mut [0];
let (ptr, len) = (slice.as_mut_ptr(), slice.len());
// Clippy notes cast_slice_from_raw_parts with this unnecessary cast:
// let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(ptr, len) } as *mut [u8];
// But not this equivalent:
let _: *mut [u8] = core::ptr::from_mut(unsafe { core::slice::from_raw_parts_mut(ptr, len) });
}
I expected to see this happen:
Four cast_slice_from_raw_parts
warnings treated as errors.
Instead, this happened:
No errors or warnings.
Version
Nightly channel
Build using the Nightly version: 1.90.0-nightly
(2025-06-23 706f244db581212cabf2)