rust-lang / rust-lang/rust-clippy

New lint: unnecessary use of std::ptr::read_unaligned() with slices

Open
#4,891 9 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint E-medium L-style T-middle
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

During safety-dance audit I've encountered the following unsafe code pattern that can be converted to safe code:

fn read_u32(bytes: &[u8]) -> u32 {
    assert!(bytes.len() >= 4); // bounds check
    unsafe { ptr::read_unaligned(*bytes as *const u32)}
}

This is common in binary format decoders that need to take a chunk of byte stream and interpret it as a value. The exact target value may vary - it can be any primitive numerical type.

Ever since TryInto got stabilized this can be rewritten in safe code with identical performance, although the safe solution is not really obvious:

fn read_u32(bytes: &[u8]) -> u32 {
    // try_into() cannot fail because slice len is always 4
    let bytes_to_convert: [u8; 4] = bytes[..4].try_into().unwrap();
    u32::from_ne_bytes(bytes_to_convert)
}

This may look like it does a lot of more and would be slower, but rustc produces identical code for both versions.

If converting to f32 or f64, the last line would instead be the following: f32::from_bits(u32::from_ne_bytes(bytes_to_convert))

See from_bits() documentation for more info on converting bytes to floats.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing existing Clippy lints that recognize unsafe pointer operations and their tests, then compare the slice pattern in the issue with equivalent safe conversions for integer and floating-point types. Done means the new lint reliably identifies the unnecessary read_unaligned pattern and avoids flagging cases that cannot be safely converted.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.