Problems with stabilizing Entry


#1

So right now Entry is “100% concrete” like the rest of collections. Each collection defines its own Entry enum and structs that all happen to provide the same API.

Longterm, with collection traits and whatnot, we presumably want there to be a single Entry enum with VacantEntries impling a VacantEntry trait, and OccupiedEntries impling an OccupiedEntry trait.

If we stabilize Entries as they are now, we are locking out this possibility by commiting to “everyone has their own enum”.

However if we try to unify the enum now, I don’t think we have the type-system necessary to handle it. In particular the Entry enum has a get method that returns Result<&'a mut V, VacantEntry>. This requires the enum to know how to called into_mut on the OccupiedEntry, which implies an OccupiedEntry trait. But I don’t think we can express the full OccupiedEntry API right now because it has these two methods:

fn get_mut(&mut self) -> &mut V
fn into_mut(self) -> &'a mut V

Basically, one borrows, and one does an iterator-like disjoint-lifetime thing. A trait that supports both would be basically crazy right now. It would have V as an associated type, but also &'a mut V? But the latter would be a totally opaque MutableRefToVal type, for which I don’t see a way to even enforce that the V’s are equal – or even that it’s a mutable reference. I suppose we can just handwave that they “should” be, but that’s pretty lame.

Finally, introducing traits would effectively lock down the API from growing in the future, without adding extra EntryV2 traits or something.


#2

I think we should stick with concrete, per-collection enums for now.

At a later point, when we’re ready to create collections traits (which means we have HKT), I believe we’ll still be able to provide an abstraction of the entry API.

We can do this by introducing a generic enum at the same time we introduce the traits. By that point, we should have have sufficient expressiveness in traits to have an OccupiedEntry trait. This will involve some redundancy, since we’ll have both collection-specific and generic Entry enums, but the specific ones can likely be deprecated at that point. (In general, laying on traits over existing code will often involve a bit of redundancy like this.)


#3

Sounds good to me.

Shipping it.