rust-lang / wg-allocators

Home of the Allocators working group: Paving a path for a standard set of allocator traits to be used in collections!
http://bit.ly/hello-wg-allocators
207 stars 9 forks source link

Tracking Issue for structs which needs an allocator #7

Open TimDiekmann opened 5 years ago

TimDiekmann commented 5 years ago

This WG wants to associate an allocator for all suitable structs. This issue tracks those structs, which are covered so far (non-exhaustive list):

Ericson2314 commented 5 years ago

I've started in https://github.com/rust-lang/rust/pull/60703 .

ErichDonGubler commented 4 years ago

@obsidianminor has asked about the Clone trait needing to also be modified:

(38183) Allocator aware std traits - rust-lang - Zulip

There's a number of traits that implicitly allocate to the global allocator like str ToOwned making a String<Global> and Clone String<Global> always making another String<Global> which would make it slightly more difficult to move data across allocators.

let  a: String<Global>  =  format!("hello world!");
let  b: String<System>  =  a.clone();  // nope, that's a String<Global>
let  b: String<System>  =  {  // we could do it manually
  let  mut  z: String<System>  =  String::new();
  z.push_str(a.as_str());
  z
};
let  b: String<System>  =  a.clone_in(System);  // or use a trait

let  s: &'static  str  =  "hello world!";
let  t: String<Global>  =  s.to_owned();
let  u: String<System>  =  s.to_owned();  // nope, it's Global again
let  v: String<System>  =  s.to\_owned\_in(System);

Is there an issue yet talking about traits like this?

Any reason this issue couldn't also accomodate Clone and any other traits/method we think of along the way? :)

lachlansneff commented 4 years ago

Thoughts on CloneIn: Clone trait instead of adding an additional clone_in method to `Clone?

ErichDonGubler commented 4 years ago

@lachlansneff: What would your motivation be for splitting into another trait?

lachlansneff commented 4 years ago

@ErichDonGubler

Adding it to Clone would be a breaking change. I can't think of a valid default implementation for Clone::clone_in and many types would have nothing to do with an allocator.

TimDiekmann commented 4 years ago

I think this should be added to the list in #15. When implementing Box and RawVec I had to limit those traits to allocators, which implements Default which is rather limiting.

TimDiekmann commented 4 years ago

However, as @SimonSapin noticed in https://github.com/rust-lang/wg-allocators/issues/15#issuecomment-489595249, it's probably fine to add them at a later point. Additionally, if you really need those traits, I think a third party trait should be possible here until landed.

ErichDonGubler commented 4 years ago

Okay. I'm guessing it'd look something like this?

pub trait CloneIn {
    type Alloc: Alloc;

    fn clone_in(&self, allocator: Self::Alloc) -> T;
}
Amanieu commented 4 years ago

Adding it to Clone would be a breaking change. I can't think of a valid default implementation for Clone::clone_in and many types would have nothing to do with an allocator.

Wouldn't just calling regular clone and ignoring the allocator be a valid default implementation?

lachlansneff commented 4 years ago

@Amanieu, how could it produce a SomeType<A> when Clone::clone would just create a SomeType<System>?

lachlansneff commented 4 years ago

@ErichDonGubler, I don't think it'd need a Alloc associated type, but it would need a generic self type I think.

pub trait CloneIn {
    type This<A: Alloc>;
    fn clone_in<A: Alloc>(&self, allocator: A) -> Self::This<A>;
}

This won't be possible until generic associated types, maybe there's another way of doing it?

ObsidianMinor commented 4 years ago

I was thinking something like

pub trait CloneIn<A: Alloc> {
    type Cloned;

    fn clone_in(&self, allocator: A) -> Self::Cloned;
}

Then you can implement it like

impl<S, A: Alloc> CloneIn<A> for String<S> {
    type Cloned = String<A>;

    fn clone_in(&self, allocator: A) -> Self::Cloned {
        String { vec: self.vec.clone_in(allocator) }
    }
}
TimDiekmann commented 4 years ago

I had this in mind:

pub trait CloneIn<B: BuildAllocRef>: Sized
where
    B::Ref: AllocRef,
{
    fn clone_in(&self, a: B::Ref) -> Self
    where
        B::Ref: AllocRef<Error = crate::Never>;

    fn try_clone_in(&self, a: B::Ref) -> Result<Self, <B::Ref as AllocRef>::Error>;
}

But this has to be enhanced by an associative Self type.

I think this should be discussed in #15 or in a new Issue.

gnzlbg commented 4 years ago

@Amanieu

Wouldn't just calling regular clone and ignoring the allocator be a valid default implementation?

How would you add this method to Clone ? (*)

IIUC what you are proposing, what would something like this do

let x: Vec<T, A>;
let y: Vec<T, U> = x.clone_in();

if Clone::clone_in is implemented on top of clone ?

(*) I can imagine that we either have Clone<A> for T which would be a breaking change, or Clone::clone_in<Other>(&self) -> Other where Self: Sized or something like that, but I'm probably missing some more obvious extension.

95th commented 4 years ago

can't we make the clone method generic:

fn clone<A = Global>(&self) -> Self where A: Alloc;
gnzlbg commented 4 years ago

@95th You would need to return a different type than Self to be able to clone a Box<T, A> into one that has a different type because it has a different allocator, e.g., Box<T, B>.

95th commented 4 years ago

@gnzlbg you're right sorry.. A type based on generic param..

Edit: I realize the problem with this

lqf96 commented 4 years ago

Do we also need to associate an allocator for owned strings types from std::ffi module? That will include CString and OSString...

TimDiekmann commented 4 years ago

On Sonntag, 10. November 2019 23:23:43 CET Qifan Lu wrote:

Do we also need to associate an allocator for owned strings types from std::ffi module? That will include CString and OSString...

Adding an associated allocator to CString should be pretty straightforward, as it's basically a Box<[u8]>. OSString depends on the Os, but this shouldn't be a problem as well. Based on this, also PathBuf may should get an allocator, too. All three have a low priority at time of writing though.

TimDiekmann commented 3 years ago

Currently, there is a PR upstream for Box and BTreeMap. After Box is merged, I'll adjust Vec and String. I updated the OP to reflect this.

cc @exrook

pickfire commented 3 years ago

When can we put Vec<T, A> into std? I keep track of vec more than the rest, maybe I can help out with vec?

TimDiekmann commented 3 years ago

I just answered the question right above. And my fat fingers clicked the wrong button :D

TimDiekmann commented 3 years ago

rust-lang/rust#77187 just got merged. I'll add an allocator parameter to Vec next.

hansihe commented 3 years ago

https://github.com/rust-lang/hashbrown/pull/133 got merged a few days ago, adding custom allocator support to hashbrown.

Would this working group be willing to accept a PR for the std HashMap and HashSet too, or is it too early?

TimDiekmann commented 3 years ago

Forwarding to hashbrown should be pretty straightforward. Currently, Vec is queued for a crater run and this will take a while. I can take a look at HashMap (+ HashSet, which is basically the same) afterwards. Thanks for the heads up!

lqf96 commented 3 years ago

@TimDiekmann It seems like efforts to add allocator to CString has stalled due to issues with generic parameter stability attributes... Would it be a good idea to turn to other data structures first, such as HashMap and HashSet suggested by @hansihe, while waiting for someone to fix the issue?

TimDiekmann commented 3 years ago

There is an open proposal #79 which would replace the allocator backend with a storage backend, which is more flexible and intuitive. This is looking very promising and I'd prefer that in favor of adding allocators to every data structure. Since recently it is in a state with which it seems worth experimenting within std.

cmazakas commented 3 years ago

Is there interest in accepting contributions implementing Allocators for the various remaining containers? I'd like to try and help knock some of those out.

TimDiekmann commented 3 years ago

Yes, very much! Since I am currently relocating, I currently have only limited time.

cmazakas commented 3 years ago

Awesome! Alright, I've got the rust repo cloned and will be making an rc-alloc branch.

Anything I should know/adhere to going forward?

SimonSapin commented 3 years ago

https://rustc-dev-guide.rust-lang.org/contributing.html#contributing-to-rust should be a good start

pickfire commented 3 years ago

After reading into that, use ./x.py setup to configure it for libs so you don't have to rebuild the whole compiler and for it to automatically download it online, that will make the development process much faster. I think the docs mention it somewhere but you need to find it, maybe you can just run that. After that you can start iterating on the libs. You might want to pick something simpler such as Rc first. Usually you only want ./x.py check or it might take a long time if you do ./x.py test or ./x.py build, at the end you might want to write some tests and do ./x.py test --bless to automatically fix the tests for you, you might also want to do test filtering.

mark-i-m commented 3 years ago

https://rustc-dev-guide.rust-lang.org/getting-started.html?highlight=setup#configuring-the-compiler may also be useful. The rustc-dev-guide is kind of geared towards the compiler itself, but a lot of the advice also applies to the standard library.

a1phyr commented 3 years ago

@TimDiekmann I have just sent a PR for VecDeque, could you add it to the top-level list ?

Cyborus04 commented 2 years ago

@TimDiekmann I made a PR for Rc in rust-lang/rust#89132, could you add that to the list?

yanchith commented 2 years ago

I might have a usecase for BinaryHeap with custom allocators. Looking at the source, BinaryHeap is just a wrapper around Vec, which is already allocatorized, so extending it to support allocator api should be relatively straightforward.. I hope.

I notice there is no linked issue. If I want to add this, should I create an issue in rust-lang/rust and go from there?

Amanieu commented 2 years ago

I think you can just go ahead and write a pull request for it. All the allocators are under the #32838 tracking issue.

rytheo commented 1 year ago

@TimDiekmann I have a PR for LinkedList here: https://github.com/rust-lang/rust/pull/103093

TimDiekmann commented 1 year ago

Thanks, updated!

yanchith commented 1 year ago

Oh, I didn't realize I had to post back here, but I made a PR for BinaryHeap some time ago, but it looks like it got buried https://github.com/rust-lang/rust/pull/99339

tgross35 commented 1 year ago

There are a few changes to the list in the issue - @TimDiekmann would you want to update these items?

TimDiekmann commented 1 year ago

Thank you, I updated the comment.

tgross35 commented 1 year ago

Rc and Arc just landed! https://github.com/rust-lang/rust/pull/89132#event-9843774823