Skip to content

Confusing diagnostic from const eval when offsetting a pointer out of bounds #93881

Closed
@saethlin

Description

@saethlin

Given the following code: playground link

#![feature(const_ptr_offset)]
const fn demo() -> *const u8 {
    let x = 0u8;
    let ptr = &x as *const u8;
    unsafe { ptr.offset(3) }
}

const P: *const u8 = demo();

fn main() {}

The current output is:

error[E0080]: evaluation of constant value failed
   --> /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:295:18
    |
295 |         unsafe { intrinsics::offset(self, count) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
    |                  pointer arithmetic failed: alloc2 has size 1, so pointer to 3 bytes starting at offset 0 is out-of-bounds
    |                  inside `ptr::const_ptr::<impl *const u8>::offset` at /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:295:18

Ideally the output should look like:

error[E0080]: evaluation of constant value failed
   --> /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:295:18
    |
295 |         unsafe { intrinsics::offset(self, count) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
    |                  pointer arithmetic failed: alloc2 has size 1, so pointer to 1 byte starting at offset 3 is out-of-bounds
    |                  inside `ptr::const_ptr::<impl *const u8>::offset` at /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:295:18

I originally found this through Miri, in huonw/primal#35, though the diagnostic is generated by rustc so I'm opening an issue here. I spent a while in the original example trying to figure out how a *const u8 became a pointer to 3 bytes. Reading over the code that implements this diagnostic, it almost looks like some generic pointer out-of-bounds code was repurposed to provide a diagnostic for invalid offsets. I'd implement an improvement myself but I really can't figure out how to get the size of the pointee type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions