TypeId exposes placeholders type generics with -Znext-solver
#130785
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