Skip to content

invalid_reference_casting false positive: dynamically sized types #121074

Closed
@dtolnay

Description

@dtolnay
fn main() {
    let x: Box<dyn Send> = Box::new(0i32);
    let z = unsafe { &*(&*x as *const dyn Send as *const i32) };
    println!("{}", z);
}

I believe this code is well defined.

It runs successfully in Miri with RUSTFLAGS='-Zcrate-attr=allow(invalid_reference_casting)' cargo +nightly miri run.

However, since #118983 (nightly-2024-02-14), the following deny-by-default lint is triggered in cargo check:

$ cargo +nightly-2024-02-14 check

error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused
 --> src/main.rs:3:22
  |
3 |     let z = unsafe { &*(&*x as *const dyn Send as *const i32) };
  |                      ^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |                          |
  |                          backing allocation comes from here
  |
  = note: casting from `dyn Send` (0 bytes) to `i32` (4 bytes)
  = note: `#[deny(invalid_reference_casting)]` on by default

Rustc thinks the dyn Send is 0 bytes, whereas for the purpose of the memory model as I understand it, it has a runtime size that is bigger than 0 bytes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions