-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Comprison of TypeId
s in const context
#73900
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
There's a snippet in the stabilization PR that compares two type ids, but it does it using const USIZE: TypeId = TypeId::of::<usize>();
match TypeId::of::<Self>() {
// Use a closure for `usize` that transmutes the generic `Self` to
// a concrete `usize` and dispatches to `Self::usize`.
USIZE => |x| Self::usize(unsafe { &*(x as *const Self as *const usize) }),
// For other types, dispatch to the generic `Self::default`.
_ => Self::default,
} |
Oh, I've missed it 🤦 Then I think this issue is not critical at all. Thanks. However const fn type_eq<A: 'static, B: 'static>() -> bool {
let A = TypeId::of::<A>();
const B: TypeId = TypeId::of::<B>(); // error[E0401]: can't use generic parameters from outer function
match A {
B => true,
_ => false,
}
} |
We could add stand-alone function and then replace it by const imply. (if we'll do this before the stabilization of stand-alone fns, it won't be even a breaking change) |
You can use associated constants to get the #![feature(const_type_id)]
use std::any::{type_name, TypeId};
pub struct GetTypeId<T>(T);
impl<T: 'static> GetTypeId<T> {
pub const VALUE: TypeId = TypeId::of::<T>();
}
#[macro_export]
macro_rules! typeid {
($t:ty) => {
$crate::GetTypeId::<$t>::VALUE
};
}
const fn same_type<T: 'static, U: 'static>() -> bool {
match typeid!(T) {
typeid!(U) => true,
_ => false,
}
}
fn print_if_equal<T: 'static, U: 'static>() {
if same_type::<T, U>() {
println!("{} == {}", type_name::<T>(), type_name::<U>());
} else {
println!("{} != {}", type_name::<T>(), type_name::<U>());
}
}
fn main() {
print_if_equal::<usize, u32>();
print_if_equal::<usize, usize>();
} Edit:
Reported this in #73976 |
Then I'll go ahead and close this issue, technically comparison can be done. The only problem is a bug reported in #73976 I've actually used similar hack with assoc const, how I could forget... anyway, thanks @rodrimati1992 |
@WaffleLapkin The pattern in #73976 is now forbidden. However you can use this transmute hack: #![feature(const_fn)]
#![feature(const_type_id)]
use std::any::TypeId;
use std::any::type_name;
use std::mem::transmute;
const fn same_type<A: 'static, B: 'static>() -> bool {
unsafe { transmute::<_, u64>(TypeId::of::<A>()) == transmute::<_, u64>(TypeId::of::<B>()) }
}
fn print_if_equal<T: 'static, U: 'static>() {
if same_type::<T, U>() {
println!("{} == {}", type_name::<T>(), type_name::<U>());
} else {
println!("{} != {}", type_name::<T>(), type_name::<U>());
}
}
fn main() {
print_if_equal::<usize, u32>();
print_if_equal::<usize, usize>();
} |
@nbdd0121 it's actually a de jure UB since (reopening the issue since the pattern from #73900 (comment) is now forbidden) |
See this pr for more information #101698. |
Is there any way to compare 2
TypeId
s inconst
context? (It's possible to create them inconst
context, and it's even soon to be stabilized)What I want is a static check for type (un)equality without
auto trait
s:(this exact code currently fails to compile with "calls in constants are limited to constant functions, tuple structs and tuple variants" error, because
==
isn'tconst
)Maybe it's a good idea to add API like the following to TypeId?
I could work on this, though I haven't seen similar apps in std, so I wanted to ask about it before doing anything.
The text was updated successfully, but these errors were encountered: