-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comprison of TypeId
s in const context
#73900
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: