Overhaul interning #481
Labels
major-change
A proposal to make a major change to rustc
major-change-accepted
A major change proposal that was accepted
T-compiler
Add this label so rfcbot knows to poll the compiler team
Proposal
The compiler uses interning a lot, especially within
rustc_middle::ty
.Pros of interning
Eq
andHash
, i.e. compare/hash the addresses of the interned value (which is guaranteed to be unique) instead of the contents. (I recently tried changing some of the highly used types likeTy
andList
to use contents-basedEq
andHash
, and got widespread instruction count increases of up to 10%, which is a lot.)Cons of interning
An obvious way to deal with interned values is to use Rust's type system to encapsulate things. Surprisingly, this isn't currently done.
rustc_data_structures::ptr_key::PtrKey<T>
, which is a smart pointer that does pointer-basedEq
andHash
. But it's barely used, barely documented, has a non-descriptive name, and has no protection against misuse.Eq
andHash
, e.g.List<T>
,Ty
,Predicate
.Eq
andHash
, e.g.Region
,Const
.I propose renaming
ptr_key::PtrKey<T>
asintern::Interned
, improving its documentation, and providing some protection against misuse:Interned<T>
but not construct anInterned<T>
.Interned::new_unchecked
for constructing values, the name of which makes it obvious that some care is required.InternedSet
,ShardedHashMap::intern
) into this module so that most places don't even need to useInterned::new_unchecked
, but instead just call anintern
method directly.I then propose using
Interned<T>
for most/all of the interned types inrustc_middle::ty
:Ty
,Predicate
,Region
,Const
,List
, etc. For some of these it will involve using a newtype instead of a typedef. E.g. thiswill become this:
Pros of this change
Eq
andHash
. Also, the use of newtypes allows methods to be impl'd directly on the frequently used types likeTy
, rather than on the infrequently used inner types likeTyS
.Eq
andHash
will give some small wins.Cons of this change
I think this is a clear improvement. TBH, I'm a bit surprised that the code isn't already like this. It's no fun to have to schlep through the code to work out which types are interned and whether they're using pointer-based
Eq
andHash
. Because of this, it took me some time to reach my current level of understanding about interning. E.g. see rust-lang/rust#91617 where I added documentation toList<T>
; prior to that PRlist.rs
had no mention of interning or uniqueness of values, and I had to ask a bunch of questions on Zulip to understand how the type worked.I also think this it's borderline whether this change needs an MCP. It will touch a lot of code but not in a deep way; it's mostly just using types to more clearly encode the existing behaviour. There are no user-visible changes, existing major types are not renamed, and it's not really an architectural change. But an MCP was requested so here it is 😄
I have already written rust-lang/rust#93148 that introduces
Interned
and changesTy
,Predicate
,Region
, andConst
. I pretty much had to write the code to make sure that the proposal was reasonable.Mentors or Reviewers
I'm planning to do the work myself, and I've already done a big chunk of it. @fee1-dead or @michaelwoerister are likely reviewers.
Process
The main points of the Major Change Process are as follows:
@rustbot second
.-C flag
, then full team check-off is required.@rfcbot fcp merge
on either the MCP or the PR.You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
The text was updated successfully, but these errors were encountered: