-
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
Tracking issue for custom allocators in standard collections #42774
Comments
There are some very interesting issues here:
|
I believe that the current design doesn't allow you to parametrize the error, so it must return the concrete error type with two arms - |
@joshlf err yes, this is predicated on us adding an associated error type. |
To support the allocator trait in the collection types, the constructors will need to be duplicated. impl RawVec<T, A>
fn with_capacity(n: usize) -> RawVec<T, HeapAlloc>;
fn with_capacity_in(n: usize, a: A) -> RawVec<T, A>;
} I personally quite like this approach. |
@Ericson2314 mentioned this:
I am currently implementing a non-trivial allocator myself (for a relocatable heap) and noticed that it don't need to keep anything around for deallocation (the type information is still needed). This still works when multible allocators are used. I wonder if this could be integrated somehow? Associated types to indicate what needs to be stored? |
So the idea is that, for allocators where all instances of the type refer to the same global singleton, you wouldn't actually need to store a reference? Presumably that wouldn't work for allocators that could actually have multiple distinct instances, right? This motivates a follow-up: if you were implementing a global singleton, couldn't you just make the actual |
Yes, for allocators with multiple instances the allocation function would benefit from non-zero knowledge. |
@s3bk How common is the case where you will only ever need to deallocate? All the standard collections and smart pointers have methods that allocate new memory from the same allocator (usually Hm, now that I think about it, those methods already need to clone the allocator, so that would potentially offer a way out. Although it's unclear to me if we can switch between storing |
@rkruppe there could be trait Alloc {
type DeallocInfo;
fn dealloc(&self, ptr: *mut T, layout: Layout);
fn dealloc_with(info: Self::DeallocInfo, ptr: *mut T, layout: Layout);
// snip
}
struct Rc<T, A: Alloc> {
dealloc: A::DeallocInfo;
// snip
}
impl<T> Rc<T, HeapAlloc> {
fn make_mut(&mut self) -> &mut T {
// use HeapAlloc to potentially clone T
}
}
impl<T, A: Alloc> Rc<T, A> {
fn make_mut_in(&mut self, a: A) -> &mut T {
// use A to potentially clone T
}
} This would keep Rc as thin as possible, not break existing code and allow to use
|
@s3bk
|
@rkruppe It looks like I was completely wrong here. Most cases are covered by Box and the others reallocate. |
Is that a problem? The key property of |
There's another angle to consider here: how do we obtain a |
@joshlf The lifetime problem is indeed tricky… What if a lifetime would be added to the Alloc trait? trait Alloc<'a> {
type DeallocInfo;
fn dealloc_info(&self) -> Self::DeallocInfo;
...
}
impl<'a> Alloc<'a> for &'a MyAllocator {
type DeallocInfo = MyDeallocInfo<'a>;
…
} |
@s3bk that's an interesting approach, but doesn't doing |
@joshlf this crude example should not be Send or Sync. So it could safely be non-theadsafe . |
@s3bk Ah I think you're right about that. Good call. |
Not quite sure where the conversation is now, but we should probably discuss type SomeCollection<T> = collections::SomeCollection<T, GlobalAlloc>; As a temporary way to get the ball rolling here without impacting breaking std, needing newtypes or language design work for default params with aliases. (Picking up the discussion from #43112 (comment).) |
Cross post #32838 (comment) I've started generalizing the collections myself; the easiest way to demonstrate how the associated return type helps is to just do the code change, I suppose. |
So, as far as I can tell, the real issue here is the one with knowing which allocator to use for further allocations or deallocation using a type. In the case of a single instance of each This would seem to achieve the best of both worlds – no additional cost whatsoever over the current situation when you use the global allocator, and the necessary (but minimum) cost when you use custom allocators. |
@alexreg I don’t think there is a need for an What happens at the moment for |
Yes that is what I did for |
@fitzgen See the |
I think this signature would work with Rust today (although I have not tried it yet): impl<T, A: Alloc> Box<T, A> {
pub fn leak<'a>(self) -> &'a T
where
A: 'a,
{ ... }
} |
Filed fitzgen/bumpalo#2 |
Has there been any progress with stabilizing this? |
@glandium just got their PR for |
@Ericson2314 @glandium Link to that PR? |
@passchaos Looks like it; thanks! |
It'd be useful if we could use the traditional collection apis ( |
As long as #27336 is not implemented, that would make some currently-valid programs ambiguous because type inference doesn’t know what allocator to pick. |
That's been feature-gated for 3 years. Can it not just be stabilized? |
Assuming yea mean #27336, it’s better discussed in the relevant tracking issue. I haven’t been following this one, but from a quick glance at the thread its implementation is not complete yet and it’s not "just" a matter of flipping the stabilization switch. |
Is there an RFC or design document talking about what the current plans for allocators in stdlib collections are? The allocators RFC leaves this stuff undecided, and this issue seems to be an implementation tracking issue. |
At this point I think we need a champion who would summarize what’s still unresolved in the (numerous) discussions so far and see, try to build consensus, and make set of proposals (possibly as a new RFC). Note that I am not volunteering at this time :] |
Such a champion might probably want to start a working group, similar to the unsafe-code-guidelines, with its own github repo, where multiple parts of the "Allocators issue" can be explored in parallel, with active meetings to make progress, and where the parts of the issue that achieve consensus get merged slowly into a document with rationale, which is then sliced into suitable RFCs. Summarizing the discussions effectively and putting them into a single comment would be a lot of work, and it won't IMO help much, because 10 people are going to answer to the summary, asking questions and discussing 10 different aspects of it. The champion of such a working group would probably need to be a core team or lib team member with the time and will to see this through, and that will probably require somehow fitting allocators in the 2019 roadmap. |
Regarding the 2019 roadmap, allocators are already the one item specifically mention for the library team in rust-lang/rfcs#2657. Though to some extent this might be wishful thinking as long as no-one steps up to lead this work. I feel that this is a much smaller topic than unsafe code guidelines, but on further thought you’re probably right that this is a better model to keep sub-discussions organized. |
Once |
I've made a post on internals where the libs team is considering spinning up a working group to drive this issue to completion, and if you're interested please feel free to comment there! |
As we now have a dedicated repository for the allocators WG this issue may be closed/locked to keep discussions in one place? |
I think this issue still serves to funnel people in the direction of that repo. Nobody will know to go there otherwise. |
I agree with @TimDiekmann that centralizing discussion is probably best now, so I'm going to close this in favor of the WG repository. I'll open an issue on the repository about discoverability. |
The new
Alloc
trait defined in RFC 1398 was added in #42313 but the libs teamdecided to hold off onVec
integration just yet to be conservative.This issue is intended to track the integration of the
Alloc
trait into standard collections likeVec
,BTreeMap
, etc. I'm not personally aware of any current blockers, but what we'll probably want to do as part of this issue includes:The text was updated successfully, but these errors were encountered: