-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Closed
Labels
A-lintArea: New lintsArea: New lints
Description
What it does
This prevents a kind of UB.
Examples:
let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
// expected to be expanded
assert_eq!(alt_slice[0], 1);
assert_eq!(alt_slice[1], 2);
assert_eq!(alt_slice[2], 3);
assert_eq!(alt_slice[3], 4);
This is not true. alt_slice[0]
have (mostly) 0x01020304
or 0x04030201
depending on byte-order, and left is looks like garbage and user thinks it is not what (s)he wanted.
Also, this contains UB. Miri reports call to transmute
is UB.
I believe: mem::transmute::<&[T], &[U]>
is UB if and only if mem::size_of<T> < mem::size_of<U>
.
Alternatives:
This may not be MachineApplicable
, because:
If user is expected to keep length and transmute each element:
// let original_slice: &[T] = ...
let alt_slice: &[U] = original_slice
.iter()
.map(|original| unsafe { core::mem::transmute(original) })
.collect::<Vec<_>>()
.as_slice()
If user is expected to transmute entire bit pattern of pointing bit-pattern:
// let original_slice: &[T] = ...
let (prefix, align_result, suffix) = original_slice.align_to::<U>();
assert_eq!(prefix.len(), 0);
assert_eq!(suffix.len(), 0);
Lint Name
transmute_to_larger_element_slice
Category
correctness
Advantage
- Prevents a kind of UB.
Drawbacks
No response
Example
// let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
Could be written as:
let alt_slice: &[u32] = original_slice
.iter()
.map(|original| unsafe { core::mem::transmute(original) })
.collect::<Vec<_>>()
.as_slice()
or
let (prefix, align_result, suffix) = original_slice.align_to::<u32>();
assert_eq!(prefix.len(), 0);
assert_eq!(suffix.len(), 0);
Metadata
Metadata
Assignees
Labels
A-lintArea: New lintsArea: New lints