indexmap
indexmap copied to clipboard
Implement get_many_mut
std::collections::HashMap is adding get_many_mut in https://github.com/rust-lang/rust/issues/97601 and I'm working on replacing some uses of that hash map with this one where some of the code uses get_many_mut (currently only a single location in rustc) so I would appreciate it if indexmap::IndexMap could provide the same interface.
This code uses a decent amount of unsafe compared to the rest of the file and I saw the comment in lib.rs on having almost all unsafe code in raw.rs but I couldn't figure out how to move parts of my implementation there as it is mostly dealing with initializing the array. I tried to use array::map to avoid all unsafe but couldn't quite get it to work with the lifetimes and the lambda.
If you want this change, I'll also write some docs.
I think ideally we would want two things for this, especially the first:
- Stabilizing
HashMap::get_many_mutso we can be sure to match that API as much as possible. - Stabilizing
<[T]>::get_many_mut(still new in rust-lang/rust#83608) to deal with all theunsafeaspects. We might also want to wrap that into our ownget_many_index_mut, just like we haveget_indexandget_index_mutfor slice-like indexing.
I tried to use
array::mapto avoid all unsafe but couldn't quite get it to work with the lifetimes and the lambda.
I suspect part of this is because you should be using a raw pointer to offset/index each of the elements, otherwise you have the main &mut [T] aliasing each of the &mut T you pull out while you're working. And of course, using raw pointers will still need unsafe to form the final references.
Stabilizing HashMap::get_many_mut so we can be sure to match that API as much as possible.
Yeah, this makes a lot of sense. Is it okay to just leave the PR open until then?
Stabilizing <[T]>::get_many_mut
Haven't seen this before but it would indeed fit pretty well. It seems to have been open for quite a while without resolution though. Also, if they opt for a result-based return value, that'd not match the hashmap api (as it is now) so we'd have to do conversions in the implementation.
I suspect part of this is because you should be using a raw pointer to offset/index each of the elements, otherwise you have the main &mut [T] aliasing each of the &mut T you pull out while you're working. And of course, using raw pointers will still need unsafe to form the final references.
Yeah, exactly, the lambda captures the whole array lifetime mutably and can't be invoked multiple times. I did not consider pointer arithmetic though, I'll experiment a bit and see how it looks. Probably similar to the <[T]>::get_many_mut examples 🙂
Is it okay to just leave the PR open until then?
Yeah, that's fine. I should probably make a label for this...
I think ideally we would want two things for this, especially the first: Stabilizing HashMap::get_many_mut so we can be sure to match that API as much as possible.
Can IndexMap add it under a nightly or unstable opt-in cargo feature? Then people will have to opt in to breaking changes, and you can document that changes to this API won't result in a new major version.
(Or if you don't feel strongly, you can just make a new major release if the HashMap API changes for some reason.)
I don't like using nightly/unstable features, in part because it's an extra maintenance burden, but also because the feature may be opted-in on your behalf, arbitrarily deep in your dependency tree.
I'd rather not set us up for needing a semver bump either. If this is something that folks really need, let's apply that pressure on std stabilization. :)