Repository navigation
Closed
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)B-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCI-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.I-libs-radarLibs issues that are tracked on the team's radar.Libs issues that are tracked on the team's radar.S-tracking-impl-incompleteStatus: The implementation is incomplete.Status: The implementation is incomplete.T-langRelevant to the language teamRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.This change is insta-stable, or significant enough to need a team FCP to proceed.
Description
This is a tracking issue for using TypeId::of in constant contexts.
The feature gate for the issue is #![feature(const_type_id)].
About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
- Come up with a new scheme for collision resistant type ids
- Figure out any safeguards we need to prevent messing with the bits of type id directly
- Adjust documentation (see instructions on rustc-dev-guide)
- Stabilization PR (see instructions on rustc-dev-guide)
Unresolved Questions
- How can we prevent abuses of transmuting type ids into integers at compile time (where we have fewer tools to deal with them)? See the discussion in Widen TypeId from 64 bits to 128. #75923
- We need a new scheme for building type ids that's collision resistant. We'd like to do this before stabilizing type ids in constant contexts. Collisions in type_id #10389, type_id is not sufficiently collision-resistant #129014
Implementation history
- Initial const implementation Turn
type_idinto a constant intrinsic #47892 - Initial stabilization Stabilize const_type_id feature #72488
- Reverted stabilization revert const_type_id stabilization #77083
Reacted by Bernard Kolobara, Benjamin Kay, Shane F. Carr, Ben, Edward Pierzchalski, cdecompilador, Evgeniy Dushistov, Tyler Neely, Slanterns, fanninpm and 24 more
Reacted by nielsle, Gabriel Bjørnager Jensen, Thierry Berger and Haled Odat
Reacted by Adam and Thierry Berger
Metadata
Metadata
Assignees
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)B-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCI-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.I-libs-radarLibs issues that are tracked on the team's radar.Libs issues that are tracked on the team's radar.S-tracking-impl-incompleteStatus: The implementation is incomplete.Status: The implementation is incomplete.T-langRelevant to the language teamRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.This change is insta-stable, or significant enough to need a team FCP to proceed.
Activity
benkay86 commentedon Jun 2, 2021
I'm not sure I totally understand the steps needed to re-stabilize
const fn TypeId::of().Does this affect the soundness of
const fn TypeId::of()? If we are really worried about collisions, then shouldn't the entirety ofTypeIdbe unstable, and not just theconstversion? Or are we worried that a future collision-resistant implementation ofTypeIdmay not satisfyconst, i.e. we want to keep open the possibility of a non-const implementation in the future?This seems impossible. If someone wants to
transmute()to the type of the private implementation (i.e.u64) in anunsafecode block, even though the documentation forTypeIdexplicitly says not to do this, can we really stop them? (They can already do it at runtime, not sure what "tools" prevent this.) Can we really stop anyone from doing unsafe things withunsafecode?Motivation: It would be extremely useful to make
constcomparisons betweenTypeIdin order to infer whether two types are equal at compile time. Currently this only appears to be possible using specialization (#31844), which is unsound and will not be stabilized anytime soon.A perhaps related concern (may need a separate tracking issue) is that
#derive[(PartialEq, Eq, ...)] struct TypeIddoes not generateconst implfor these traits (see #77695), so even ifconst fn TypeId::of()gets re-stabilized we still won't be able to compare types at compile time without writing aconst impl PartialEq for TypeId, etc.jmeggitt commentedon Aug 9, 2021
Can this be re-stabilized now?
@KodrAus Going through the comment that was the basis of reverting stabilization (#75923 (comment)):
Part 1
Sure, but this suggests that retrieving a
TypeIdshould beunsafenotunstable.Anyis currently both stable and safe despite heavily relying onconst fn TypeId::of(). If there are serious concerns thatconst fn TypeId::of()may result in collisions thenAnyshould be unstable as well.Part 2
I think @benkay86 summed this up fairly well.
Part 3
And finally, @eddyb remarks that we could potentially re-stabilize it if we are unlikely to change it.
It has been nearly 10 months since it was marked unstable and there have been no changes regarding this issue. At this point it seems like the implementation of
TypeIdis unlikely to change any time in the near future.TL;DR
Plus even if we assume all of these points are true, these concerns only apply to
intrinsics::type_id::<T>() -> u64notconst fn TypeId::of::<T>() -> TypeId.If anything, the heavy reliance on
const fn TypeId::of()insideAnysuggests that it is stable but could potentially be unsafe to use directly. If there are concerns thatTypeIdcan be abused without unsafe code thenconst fn TypeId::of()should be marked as unsafe instead. However I do not think this is necessary since you would need to usetransmute()to extract the raw type id integer fromTypeId.intrinsics::type_id::<T>()should remain unstable as it provides access to the raw type id integer, butconst fn TypeId::of()should be stabilized as it provides adequate protection.eddyb commentedon Aug 9, 2021
Nobody tried AFAIK. 10 months is pretty short on the scale of Rust evolution, especially when you take into account the year 2020.
But also I believe it got stalled because of this potential breakage: #75923 (comment)
In order to guarantee code that
transmutes tou64gets broken, we can't just replaceTypeIdwith a pointer, but because we still want the 64-bit hash (for both "fast reject (!=)" andHash, see #75923 (comment)), we can probably do this:That way, it's always more than 8 bytes, no matter the target pointer size, and so a
transmutetou64will always error.As for the linker concerns, if we take this specific approach, the only difference relying on their features would make is increasingly the situations in which the "fast accept (
==)" path gets taken, i.e. an optimization.I could try make a PR for this, but it would likely at least require #87194 (to avoid breaking when unstable
constgeneric features are used).But we don't want that. You can't change
TypeIdorAnyto beunsafe, they're stable, and nearly-sound.programmerjake commentedon Aug 9, 2021
Maybe it would be better to use this to shrink
TypeIdto only 16 bytes on 64-bit platforms:eddyb commentedon Aug 10, 2021
Yeah, that's what I meant by "length-prefixed". There's a "standard" way to do that using
extern { type }, I just didn't want to type it in.eddyb commentedon Apr 9, 2022
Update: finally opened #95845 with a (v0) mangling-based
TypeIdrepresentation (should unblockconst fnTypeId::of, while at the same time making specific uses ofTypeIdincompatible with CTFE, for now).lcnr commentedon May 18, 2022
blocking the stabilization of this on #97156
76 remaining items
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Unrolled build for #144133
Rollup merge of #144133 - oli-obk:stabilize-const-type-id, r=lcnr
Rollup merge of #144133 - oli-obk:stabilize-const-type-id, r=lcnr
Rollup merge of rust-lang#144133 - oli-obk:stabilize-const-type-id, r…
Rollup merge of #144133 - oli-obk:stabilize-const-type-id, r=lcnr
Rollup merge of #144133 - oli-obk:stabilize-const-type-id, r=lcnr