-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: TypeInfo #2738
base: master
Are you sure you want to change the base?
RFC: TypeInfo #2738
Conversation
I think the idea itself is fine, but it's actually pushing cc #2280 |
And I think this trait can be named "TypeInfo", and can have another method |
I've added the two suggestions from @KrishnaSannasi ("We could say that the blanket impl is for convenience and the unsafe marking makes it safe even in the presense of specialization (whatever form that takes)") and @crlf0710 ("And I think this trait can be named "TypeInfo", and can have another method type_name which calls std::any::type_name.") |
@leo60228 can you update the pr description to include Also, we could make the |
@KrishnaSannasi |
@Centril I wasn't proposing that it be the only way to check for correctness, just another measure we could take in addition to using the typeid hash. Of course this could also be folded into This only relies on the fact that the same type will always give the same type name, so this should be fine (same as typeid, the same type gives the same hash). |
Personally, actually I think it's compiler responsibility to detect TypeId hash collisions at compile time, and replace TypeId for either of the collision types to a hash value that's not used. And if every possible hash value is used, i think a compile error should be raised at compile time. |
@KrishnaSannasi That seems like a hack for dealing with the soundness hole in rust-lang/rust#10389. Preferably we'd fix the problem at its root instead of papering over it. |
maybe there should be a note about how including |
I'm extremely confused why this type is different from Honestly, as someone unfamiliar to how the What's to stop a user who wants downcasting to Just Work from using the wrong one of the two and causing loads of problems down the line? I don't know how this is affected by this RFC. My gut says that |
|
Then why not just give this treatment to |
It would be a breaking change, any code that relies on fn foo<T: Any>(t: T) -> Box<dyn Any> {
Box::new(t)
} Because |
Why is the 'static bound needed at all? Why not remove it and give a type id for the lifetime-erased version of the type, and put the 'static bound on the downcasting functions instead? |
It is needed to prevent transmuting lifetimes, this is because lifetimes cannot affect code-gen. So all references to a type edit: Based on what @RalfJung posted below, |
But Rust also has higher-ranked lifetime quantification, so you can introduce new lifetimes... I tried to break this but failed: use std::any::TypeId;
type T1 = for<'a> fn(&'a i32) -> &'a i32;
type T2 = for<'a> fn(&'a i32) -> &'static i32;
fn main() {
// somehow it can distinguish these even though they only differ in their lifetime
assert_ne!(TypeId::of::<T1>(), TypeId::of::<T2>());
} Do we have tests ensuring this?^^ |
check against more collisions for TypeId of fn pointer Cc rust-lang/rfcs#2738 (comment)
check against more collisions for TypeId of fn pointer Cc rust-lang/rfcs#2738 (comment)
check against more collisions for TypeId of fn pointer Cc rust-lang/rfcs#2738 (comment)
Well, we can create a new module inside of |
Add a new unsafe trait TypeInfo to core::any, and implement it for all types. This has a method type_id with the signature
fn type_id(&self) -> TypeId where Self: 'static
, as well as a method type_name with the signaturefn type_name(&self) -> &'static str
. Traits wanting to support downcasting can add it as a supertrait, without breaking backwards compatibility.This was originally written to enable the functionality of
Error::type_id
to be soundly utilized in stable Rust. However, this is a more impactful change, since it would possibly remove an existing, albeit unstable, method on a widely-used trait.Pre-RFC
Rendered