-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
btree: avoid forcing the allocator to be a reference #98178
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
r? @thomcc (rust-highfive has picked a reviewer for you, use r? to override) |
Ah there are still some |
Could this be changed to require |
I figured Copy would be simpler and good enough since every allocator can be made Copy by using &A. But yeah it can probably be Clone. Not sure when I will get around to do that.
|
I agree Clone sounds better, at least if it's what HashMap does. @rustbot label +S-waiting-on-author -S-waiting-on-review |
Okay I made it |
It holding an |
In fact, it's always hard to use |
This is blocking getting Miri to work again (#98107), so would be good to get it landed soon. :) |
Thanks, this looks fine to me. @bors r+ |
📌 Commit 3a1e114 has been approved by |
@bors p=1 |
☀️ Test successful - checks-actions |
Finished benchmarking commit (ff86b27): comparison url. Instruction count
Max RSS (memory usage)Results
CyclesResults
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression Footnotes |
The struct AllocRef<'a, A> {
allocator: [&'a A; (size_of::<A>() > 0) as usize],
}
impl<'a, A: Allocator> Deref for AllocRef<'a, A> {
type Target = A;
fn deref(&self) -> &A {
// This should be fine?
self.allocator.get(0).unwrap_or_else(|| unsafe { NonNull::dangling().as_ref() })
}
}
impl<'a, A> Copy for AllocRef<'a, A> {}
impl<'a, A> Clone for AllocRef<'a, A> {
...
} which preserves the size of ZSTs but doesn't unnecessarily require |
This sounds like something a user of BTreeMap / HashMap could also do? |
No, because that would require the allocator to be a reference. The problem is that some allocators cannot be cloned, but the If something like |
@joboet That's very clever. Are you interested in submitting a PR for it? |
Oh I see, so you want BTreeMap to own the allocator but the |
Allowing |
If that internal helper function creates a IOW, for the default allocator |
I understand. But then I don't understand the use of Allocator + Clone everywhere and not Allocator + Copy (obviously, it would be better without Clone but I sure don't know how). An allocator is used for efficiency, as far as I know. A allocator used in a BTreeMap (and I assume in hashbrown too) can only be used efficiently if it is cheap to clone, because cloning happens all over the place. If people are prepared to implement Clone but not to commit to Copy, why lure them into using it in a map? |
Yeah, well, I was in favor of Anyway discussions on closed PRs are not usually a good idea, so it'd probably be better if you opened a new issue for this. |
I found it’s really hard to implement an allocator with reference but without Arc. The struct who owned the map will also owns the allocator itself, which means that it’s unavoidable to introduce Pin, pin_project, and many other complicated and even unsafe codes to implement the self-referential data structure. Using Arc here at least can make it simple and clear. |
The previous code forces the actual allocator used to be some
&A
. This generalizes the code to allow anyA: Copy
. If people truly want to use a reference, they can use&A
themselves.Fixes #98176