rust-lang / rust-lang/rust

False positive for path statement with no effect; removing path would hide bug

Open
#131,504 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
pub trait SameSize {
    const CHECK_SIZE: ();
}

impl<Src: Sized, Dst: Sized> SameSize for (Src, Dst) {
    const CHECK_SIZE: () = assert!(size_of::<Src>() == size_of::<Dst>());
}

pub fn cast_ptr<Src, Dst>(ptr: *const Src) -> *const Dst
where
    (Src, Dst): SameSize,
{
    // Force the size check to be evaluated at compile time
    <(Src, Dst) as SameSize>::CHECK_SIZE;

    ptr.cast()
}

fn main() {
    let ptr: *const u32 = &1;

    let _works = cast_ptr::<_, core::num::NonZero<u32>>(ptr);

    let _fails = cast_ptr::<_, u64>(ptr); // Compile-time error
}
Current output
Compiling playground v0.0.1 (/playground)
warning: path statement with no effect
  --> src/main.rs:14:5
   |
14 |     <(Src, Dst) as SameSize>::CHECK_SIZE;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(path_statements)]` on by default

error[E0080]: evaluation of `<(u32, u64) as SameSize>::CHECK_SIZE` failed
 --> src/main.rs:6:28
  |
6 |     const CHECK_SIZE: () = assert!(size_of::<Src>() == size_of::<Dst>());
  |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: size_of::<Src>() == size_of::<Dst>()', src/main.rs:6:28
  |
  = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant encountered
  --> src/main.rs:14:5
   |
14 |     <(Src, Dst) as SameSize>::CHECK_SIZE;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

note: the above error was encountered while instantiating `fn cast_ptr::<u32, u64>`
  --> src/main.rs:24:18
   |
24 |     let _fails = cast_ptr::<_, u64>(ptr); // Compile-time error
   |                  ^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0080`.
warning: `playground` (bin "playground") generated 1 warning
error: could not compile `playground` (bin "playground") due to 1 previous error; 1 warning emitted
Desired output
Compiling playground v0.0.1 (/playground)
error[E0080]: evaluation of `<(u32, u64) as SameSize>::CHECK_SIZE` failed
 --> src/main.rs:6:28
  |
6 |     const CHECK_SIZE: () = assert!(size_of::<Src>() == size_of::<Dst>());
  |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: size_of::<Src>() == size_of::<Dst>()', src/main.rs:6:28
  |
  = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant encountered
  --> src/main.rs:14:5
   |
14 |     <(Src, Dst) as SameSize>::CHECK_SIZE;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

note: the above error was encountered while instantiating `fn cast_ptr::<u32, u64>`
  --> src/main.rs:24:18
   |
24 |     let _fails = cast_ptr::<_, u64>(ptr); // Compile-time error
   |                  ^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground` (bin "playground") due to 1 previous error
Rationale and extra context

The code here checks that the source pointee and destination pointee have the same size. Thus the _works line should be fine as u32 and NonZero<u32> have the same size, but the _fails line should cause a compile-time error as u32 and u64 have different sizes.

The path statement <(Src, Dst) as SameSize>::CHECK_SIZE; is required for the constant CHECK_SIZE to be checked, otherwise there never is a check at compile time, and the _fails line would fail to catch a mismatch. Removing the path statement would cause the compilation to erroneously not fail.

Other cases

No response

Rust Version
rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: x86_64-unknown-linux-gnu
release: 1.81.0
LLVM version: 18.1.7
Anything else?

No response

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

Reproduce the report from the src/main.rs example with rustc 1.81.0, then compare the current and desired diagnostics. Investigate the path_statements warning while preserving the compile-time size check; it is done when the false-positive warning is removed without allowing the mismatched u32/u64 cast to compile silently.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.