rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.98k stars 12.68k forks source link

Tracking issue for non_static_type_id #41875

Closed eddyb closed 4 years ago

eddyb commented 7 years ago

This is a tracking issue for the RFC "1849" (rust-lang/rfcs#1849).

Steps:

bluss commented 4 years ago

Agreed, and that's a problem because there is no way to write that restriction as a where clause on a function, like for example fn type_equals<T, U>() -> bool; For example I'd start with exactly where U: 'static, but as you say, it's not enough to lead to soundness. I'd only use it in unsafe code where I could verify myself that the input to U would be lifetime free.

Avi-D-coder commented 4 years ago

Even here - yes, it would be wrong to compare &f64 and &'static f64 for "type equality", but that's not a needed feature in this use case.

@bluss why is it wrong, to compare &f64 and &'static f64, according to the RFC they will always have the same TypeId, since lifetimes are erased.

bluss commented 4 years ago

If I understand correctly, it would be an ok verdict from the function itself, it's just dangerous if users act on it, for example, you might assume that if two types are equal (according to that comparison), then you can freely cast a raw pointer to one to the other type, and this breaks down with types that have lifetimes.

Avi-D-coder commented 4 years ago

I think part of the problem with the conversation in this issue is we all mean slightly different things by type equality, wrong, safe and unsound.

If a cast is made as a result of the erroneous belief that TypeId equality implies lifetime equality, then I would say the cast is wrong/unsound not the TypeId comparison. And I might say type equality has been established, dispite the lack of lifetime equality.

While this feature clearly can be a foot-gun. The solution is to document that TypeId is blind to lifetimes rather than undoing the RFC. The ability to compare lifetime erased types is very useful to me, and the various workarounds are not general purpose. The confusion about and various unsound uses of this feature, could very well be a result of not reading the RFC, since the docs don't mention lifetime erasure at all.

If this feature were added to nightly with updated doc I don't think there would be very much confusion.

joshtriplett commented 4 years ago

@rfcbot cancel

rfcbot commented 4 years ago

@joshtriplett proposal cancelled.

joshtriplett commented 4 years ago

@rfcbot close

rfcbot commented 4 years ago

Team member @joshtriplett has proposed to close this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

rfcbot commented 4 years ago

:bell: This is now entering its final comment period, as per the review above. :bell:

nikomatsakis commented 4 years ago

It's probably worth adding a bit of context here. We discussed this in our recent @rust-lang/lang team meeting and the general feeling was that this feature just felt like it wasn't adding enough value, given the potential for confusion and misuse.

rfcbot commented 4 years ago

The final comment period, with a disposition to close, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

nikomatsakis commented 4 years ago

I don't believe this was ever implemented. I have pushed an update to the RFC indicating it was retracted. I'm going to close the tracking issue now.

dtolnay commented 2 years ago

I put up a pre-RFC in https://internals.rust-lang.org/t/pre-rfc-non-footgun-non-static-typeid/17079 with a counterproposal that unblocks many of the use cases that wanted non-'static TypeId, but in a way that does not open up the risks that have been discussed above in this issue.

eddyb commented 2 years ago

There was one usecase which came up early on IIRC, that wouldn't be solved by the "dynamic conservative : 'static check" shenanigans, which was something like TypeId::of::<Foo<'a>>() being used as a workaround TypeId::of::<FooTag>().

Nevertheless, I'm extremely wary of anything allowing actual lifetimes in there, compared to only doing the : 'static check in a different way (which "just" requires good API design & docs).

(If anyone is wondering what it takes to have an Any that soundly handles lifetimes, I sketched the kind of necessary design recently: https://github.com/sagebind/castaway/pull/6#issuecomment-1150952050 - if you're doing MyAny<'a> and it doesn't look at least half as complicated as that sketch, it's probably wrong and can be misused to transmute lifetimes away)