Skip to content

Partial pointers in padding can make const-eval fail #148470

@theemathas

Description

@theemathas

I'm not sure if this is a bug or not.

#![allow(unused)] #[repr(C, align(16))] #[derive(Clone, Copy)] struct Thing { x: u128, y: u64, // Replace the above line with the below line to make it stop compiling // y: std::mem::MaybeUninit<u64>, // 8 bytes of padding here } #[derive(Clone, Copy)] union PreservePad { thing: Thing, bytes: [u8; 32], } const A: Thing = unsafe { let mut buffer = [PreservePad { bytes: [0u8; 32] }; 2]; (&raw mut buffer).cast::<&i32>().byte_add(28).write_unaligned(&1); buffer[0].thing }; fn main() {}

The above code compiles fine, even in Miri. However, changing the y: u64line to y: std::mem::MaybeUninit<u64> causes the following compile error:

error[E0080]: unable to read parts of a pointer from memory at alloc4 --> src/main.rs:21:5 | 21 | buffer[0].thing | ^^^^^^^^^^^^^^^ evaluation of `A` failed here | = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported For more information about this error, try `rustc --explain E0080`. 

It seems that copying Thing in consteval discards the padding if y is a u64, but copies the padding if y is a MaybeUninit<u64>. This is implemented in the compiler here and here.

Normally, this implementation detail is observable in user code only by, say, printing padding bytes after doing a copy, which is UB. However, the compiler also cares about the contents of padding bytes potentially containing pointer fragments, making the implementation detail observable in user code without invoking UB.

cc @RalfJung

Somewhat related to #147959 and #148259, but this issue doesn't depend on those two issues.

Meta

Reproducible on the playground with stable rust version 1.91.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ABIArea: Concerning the application binary interface (ABI)A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.I-lang-nominatedNominated for discussion during a lang team meeting.P-lang-drag-1Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-langT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions