Skip to content

TypeId exposes placeholders type generics with -Znext-solver #130785

Open
@meltah

Description

So, this isn't necessarily a bug, it's just interesting behavior and I'm not sure if it's intended:

#![feature(const_type_id, generic_const_exprs)]
const fn type_id<T: 'static>() -> u128 {
    unsafe { std::mem::transmute::<_, u128>(std::any::TypeId::of::<T>()) }
}

const fn c<X: 'static>() -> usize {
    // A: the evaluated program panicked at '63102938254854923095314763309601158984'
    const_panic::concat_panic!(type_id::<X>());
}

pub fn u<X: 'static>() {
    let _: [(); c::<X>()];
    println!("{}", type_id::<X>()); // B
}

This happens without even calling u. The values printed at A and B (by commenting out the call to c and adding a call to u with any arbitrary type) are different. I'm posting this issue because I'm not sure if there's ICE potential here, for values being different in a const vs runtime context.

I stumbled across this while looking for a way to make a "commutative type" i.e. where Com<A, B> and Com<B, A> are the same type. It only works in -Znext-solver and I believe that's due to -Znext-solver eagerly evaluating stuff using these placeholder types?

#![feature(const_type_id, core_intrinsics, generic_const_exprs)]
#![allow(warnings)]
struct Foo; struct Bar;

struct Bool<const B: bool>;

trait TrueOrFalse {
    type Ite<Then, Else>;
}

impl TrueOrFalse for Bool<true> {
    type Ite<Then, Else> = Then;
}

impl TrueOrFalse for Bool<false> {
    type Ite<Then, Else> = Else;
}

type Ite<const B: bool, T, E> = <Bool<B> as TrueOrFalse>::Ite<T, E>;

trait Map<T: 'static, U: 'static> where {
    type Output;
}

impl<T: 'static, U: 'static> Map<T, U> for (T, U) {
    type Output = Ite<{
        std::intrinsics::type_id::<T>() > std::intrinsics::type_id::<U>()
    }, (U, T), (T, U)>;
}

pub fn u<X: 'static, Y: 'static>() {
    let _x: <(X, Y) as Map<X, Y>>::Output = loop {};
    let mut _y: <(Y, X) as Map<Y, X>>::Output = loop {};
    _y = _x;
}

pub fn f() {
    u::<Foo, Bar>();
}

If this does happen to be fixed in a way which breaks the code above it would be nice to have a (perma-unstable) way to order types.

Meta

rustc 1.79.0-nightly (aed2187d5 2024-04-27)
binary: rustc
commit-hash: aed2187d53b8789e3a37f50ae36f894a2a679077
commit-date: 2024-04-27
host: x86_64-pc-windows-msvc
release: 1.79.0-nightly
LLVM version: 18.1.4

Activity

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

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-generic_const_exprs`#![feature(generic_const_exprs)]`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