Skip to content

[tracking issue] raw ptr to usize cast inside constants #51910

Closed
@oli-obk

Description

@oli-obk
Contributor

This is the tracking issue for the const_raw_ptr_to_usize_cast feature.

Activating the feature allows casting *const T and *mut T to usize.

I did not open an RFC for this because I believe we want to experiment with the feature (and we can already emulate it with union transmute hacks).

Activity

added
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)
on Jun 29, 2018
crlf0710

crlf0710 commented on Sep 15, 2018

@crlf0710
Member

Just encountered this, when i try to define a constant that uses ::winapi::um::winuser::IDC_ARROW as an integer, which is defined as:

pub const IDC_ARROW: LPCWSTR = 32512 as LPCWSTR;

oli-obk

oli-obk commented on Oct 1, 2018

@oli-obk
ContributorAuthor

@crlf0710 what is your use case for casting a raw pointer to an integer? Is there any reason you can't use *const () or something similar?

crlf0710

crlf0710 commented on Oct 2, 2018

@crlf0710
Member

@oli-obk actually it is an integer in the first place, however the upstream library (winapi) cast the integer to a raw pointer (maybe for convenience using it together with the raw Windows APIs) when it defined that variable (see above comment). So i can't use the original integer value in constant evaluation context now :(

I can work around this by (re-)defining those integers myself again. (Arguably the winapi crate can change its definitions to avoid this.) I'm not seeking for any changes, just want to record this use case.

oli-obk

oli-obk commented on Oct 2, 2018

@oli-obk
ContributorAuthor

I can offer you a stable workaround, but it's very unsafe and if you screw up by placing a real pointer in an integer constant we will error, and if we don't, we might so in the future. If you do undefined behaviour at compile-time, it means the behaviour (compilation success) is also undefined.

union Transmuter {
    from: LPCWSTR,
    to: usize,
}
const MY_CONST: usize = unsafe { Transmuter { from: IDC_ARROW }.to };
crlf0710

crlf0710 commented on Oct 2, 2018

@crlf0710
Member

@oli-obk Great to know, thanks a lot!

added
T-langRelevant to the language team
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
on Dec 1, 2018
MSxDOS

MSxDOS commented on Jul 15, 2019

@MSxDOS

if you screw up by placing a real pointer in an integer constant we will error, and if we don't, we might so in the future.

I'm confused, what's wrong with putting a real pointer in an integer constant?

Btw, the following code compiles just fine:

use std::ptr::null;

#[repr(C)]
struct Fields {
    field1: u32,
    field2: [u8; 3],
    field3: u64,
    field4: i32,
}

union Transmuter<T: 'static> {
    ptr: *const T,
    reference: &'static T,
    integer: usize,
}

const FIELD4_OFFSET: usize =
    unsafe { Transmuter { reference: &(Transmuter { ptr: null::<Fields>() }.reference).field4 }.integer };

const _STATIC_ASSERT_EQ_: [(); 16] = [(); FIELD4_OFFSET];

43 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)B-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-langRelevant to the language team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @comex@Geobert@RalfJung@oli-obk@crlf0710

      Issue actions

        [tracking issue] raw ptr to usize cast inside constants · Issue #51910 · rust-lang/rust