Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

size_of_in_element_count false positive with u8 element type #6590

Open
jturner314 opened this issue Jan 15, 2021 · 3 comments
Open

size_of_in_element_count false positive with u8 element type #6590

jturner314 opened this issue Jan 15, 2021 · 3 comments
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have

Comments

@jturner314
Copy link

Lint name: size_of_in_element_count

I tried this code:

fn u8_as_bytes(x: &u8) -> &[u8] {
    unsafe {
        let ptr: *const u8 = x;
        std::slice::from_raw_parts(ptr.cast::<u8>(), std::mem::size_of::<u8>())
    }
}

I expected to see this happen: Clippy should not give a size_of_in_element_count error.

Instead, this happened for rustup run nightly cargo clippy:

error: found a count of bytes instead of a count of elements of `T`
 --> src/main.rs:4:54
  |
4 |         std::slice::from_raw_parts(ptr.cast::<u8>(), std::mem::size_of::<u8>())
  |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[deny(clippy::size_of_in_element_count)]` on by default
  = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#size_of_in_element_count

In contrast, clippy (correctly) does not give an error for this code:

fn u32_as_bytes(x: &u32) -> &[u8] {
    unsafe {
        let ptr: *const u32 = x;
        std::slice::from_raw_parts(ptr.cast::<u8>(), std::mem::size_of::<u32>())
    }
}

In other words, I've seen the false positive only for the u8 case.

The false positive also occurs for the following similar code, but again, only for the u8 case:

fn u8_slice_as_bytes(slice: &[u8]) -> &[u8] {
    unsafe {
        std::slice::from_raw_parts(
            slice.as_ptr().cast::<u8>(),
            slice.len() * std::mem::size_of::<u8>(),
        )
    }
}

You might wonder why anyone would write a functions like u8_as_bytes or u8_slice_as_bytes. This came up for me because they're in a macro that implements a trait, and the macro is used for all the numeric primitives, including u8. (Here's the CI failure for my crate due to the clippy lint.)

Meta

  • rustup run nightly cargo clippy -V: clippy 0.1.51 (a62a760 2021-01-13)
  • rustup run nightly rustc -Vv:
    rustc 1.51.0-nightly (a62a76047 2021-01-13)
    binary: rustc
    commit-hash: a62a76047ea24aad7639f14eb3ce0e620b77bdb7
    commit-date: 2021-01-13
    host: x86_64-unknown-linux-gnu
    release: 1.51.0-nightly
    
@jturner314 jturner314 added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Jan 15, 2021
@ThibsG
Copy link
Contributor

ThibsG commented Jan 15, 2021

Seems related to #6511 where there is the same use of std::slice::from_raw_parts function

@ghost
Copy link

ghost commented Jan 21, 2021

When the result is &[u8], the number of elements is the same as the number of bytes and we don't need to lint. Right? 🤔

@jturner314
Copy link
Author

jturner314 commented Jan 21, 2021

Yeah, when the result of std::slice::from_raw_parts is &[u8], the size_of_in_element_count lint shouldn't apply. The description of the lint says:

What it does

Detects expressions where size_of::<T> or size_of_val::<T> is used as a count of elements of type T

Why is this bad

These functions expect a count of T and not a number of bytes

When the output is &[u8], it's clear that providing a number of bytes to the function is correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have
Projects
None yet
Development

No branches or pull requests

2 participants