Open stepancheg opened 1 year ago
TypeId
already works for non-static types by doing this:
use core::any::TypeId;
use core::marker::PhantomData;
use core::mem;
pub fn non_static_type_id<T: ?Sized>() -> TypeId {
trait NonStaticAny {
fn get_type_id(&self) -> TypeId where Self: 'static;
}
impl<T: ?Sized> NonStaticAny for PhantomData<T> {
fn get_type_id(&self) -> TypeId where Self: 'static {
TypeId::of::<T>()
}
}
let phantom_data = PhantomData::<T>;
NonStaticAny::get_type_id(unsafe {
mem::transmute::<&dyn NonStaticAny, &(dyn NonStaticAny + 'static)>(&phantom_data)
})
}
This produces TypeId
values which are 100% compatible with ones obtained in the usual way.
fn assert_t_is_str<T>() {
assert_eq!(non_static_type_id::<T>(), TypeId::of::<&str>());
}
fn main() {
assert_t_is_str::<&str>();
}
@dtolnay thanks!
It is even optimized properly (compiler explorer).
And even works in const context if we add
#![feature(const_trait_impl)]
#![feature(effects)]
If
TypeId::of
accepted non-static types,better_any
implementation would be much simpler, right?If so, should we try to ask rust-lang team to accept non-static types in
TypeId::of
?Context: we are not using
better_any
, but we have similar implementation in our library. We looked atbetter_any
to fix unsoundness issue in our implementation. We could not find unsoundness inbetter_any
(and in our fixed implementation).