Skip to content

How should const generics with references work around pointer identity and padding? #120961

@RalfJung

Description

@RalfJung

Const generics currently completely deconstruct the value into a valtree and then reconstruct it, which destroys pointer identity. As long as this is just about purely immutable const values we might be able to argue that they "don't have pointer identity" (though it is entirely unclear to me what exactly that should mean). But if consts can point to statics, that doesn't really work any more.

Example:

#![feature(const_refs_to_static)]
#![feature(adt_const_params)]

static FOO: usize = 42;
const BAR: &usize = &FOO;
fn foo<const X: &'static usize>() {
    if std::ptr::eq(X, &FOO) {
        println!("activating special mode");
    }
}

fn main() {
    foo::<BAR>();
}

Arguably this should print, but currently it does not.

Cc #95174, #119618

Similarly, this example demonstrates that padding is lost when passing an &(u8, u16) as a const generic, which is not how passing a reference usually behaves:

#![feature(const_refs_to_static)]
#![feature(adt_const_params)]

static FOO: u32 = 0x01020304;
const BAR: &(u8, u16) = unsafe { std::mem::transmute(&FOO) };

fn foo<const X: &'static (u8, u16)>() {
    let val: &u32 = unsafe { std::mem::transmute(X) };
    println!("{val:#x}"); // prints 0x1020004
}

fn main() {
    foo::<BAR>();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)F-unsized_const_params`#![feature(unsized_const_params)]`T-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