]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/src/docs/cast_slice_different_sizes.txt
Auto merge of #104673 - matthiaskrgr:rollup-85f65ov, r=matthiaskrgr
[rust.git] / src / tools / clippy / src / docs / cast_slice_different_sizes.txt
1 ### What it does
2 Checks for `as` casts between raw pointers to slices with differently sized elements.
3
4 ### Why is this bad?
5 The produced raw pointer to a slice does not update its length metadata. The produced
6 pointer will point to a different number of bytes than the original pointer because the
7 length metadata of a raw slice pointer is in elements rather than bytes.
8 Producing a slice reference from the raw pointer will either create a slice with
9 less data (which can be surprising) or create a slice with more data and cause Undefined Behavior.
10
11 ### Example
12 // Missing data
13 ```
14 let a = [1_i32, 2, 3, 4];
15 let p = &a as *const [i32] as *const [u8];
16 unsafe {
17     println!("{:?}", &*p);
18 }
19 ```
20 // Undefined Behavior (note: also potential alignment issues)
21 ```
22 let a = [1_u8, 2, 3, 4];
23 let p = &a as *const [u8] as *const [u32];
24 unsafe {
25     println!("{:?}", &*p);
26 }
27 ```
28 Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length
29 ```
30 let a = [1_i32, 2, 3, 4];
31 let old_ptr = &a as *const [i32];
32 // The data pointer is cast to a pointer to the target `u8` not `[u8]`
33 // The length comes from the known length of 4 i32s times the 4 bytes per i32
34 let new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16);
35 unsafe {
36     println!("{:?}", &*new_ptr);
37 }
38 ```