Skip to content

CTFE keeps values in padding, breaking structural equality of const generic args. #70889

Closed
@eddyb

Description

@eddyb

This example should do one of these three things, but it doesn't (playground):

  • compile successfully (PADDED == FILLED after all, field-wise)
  • error on FILLED's definition (due to evaluated constant not fitting type)
  • error when FILLED is used as an argument to Phantom
#![feature(const_generics)]

union Transmute<T: Copy, U: Copy> {
    from: T,
    to: U,
}

const PADDED: (u8, u16) = (0, 0);
const FILLED: (u8, u16) = unsafe { Transmute { from: [0u8; 4] }.to };

struct Phantom<const X: (u8, u16)>;

fn test(x: Phantom<PADDED>) -> Phantom<FILLED> {
    x
}

Instead, Phantom<PADDED> and Phantom<FILLED> are considered different types.

If we want to make it compile, we could normalize FILLED to also have that padding byte marked as "undef", but I'm not sure if we can do this normalization if the values were behind a reference.

So we might want to error if e.g. &[0u8; 4] was transmuted to &(u8, u16), because normalizing it would change what runtime code would see. Again, we have two places where we can error.


If we want to error without causing no breaking changes, either always or just indirect case, we can do so by introducing a second, stricter, validity check in ty::Const Well-Formed rules (which we should be able to post-#70107).
That check should enforce that the value is a tree of constructors (&_ would be treated as a constructor) with integer leaves (no relocations, i.e. no raw/fn pointers), where any user ADTs are structurally-matchable, and all padding bytes (not occupied by leaves) are "undef".

cc @rust-lang/wg-const-eval @varkor @yodaldevoid

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-genericsArea: const generics (parameters and arguments)A-valtreeArea: Value trees or fixed by value treesC-bugCategory: This is a bug.F-const_generics`#![feature(const_generics)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions