I want to have a DataAllocator that can return data with lifetime 'r, so I can pass it to something and still be able to return the value allocated inside something:
error[E0515]: cannot return value referencing local data `*buffer`
--> src/lib.rs:42:5
|
40 | let data = Data{a: (*buffer).as_ref()};
| ------------------ `*buffer` is borrowed here
41 | for e in data.iter(){}
42 | data
| ^^^^ returns a value referencing data owned by the current function
The problem is that if I try to iterate over data, then it complains that I'm trying to return something that is borrowed by the .iter() function. I think it might have to do with me saying that .iter() borrows the Data for the lifetime 'b, which is the entire lifetime of the allocated data. What can I do in this case?
The Box<dyn AsRef<[T]>> is needed because I want to return not only slices.
Also, what if I want an allocator that returns a data with a different lifetime? I don't see why -> Box<dyn AsRef<[T]> + 'r> is bad.
Remember that the data allocator can have its own lifetime, but I want to create, inside do_something, a data with a buffer allocated from data_allocator.
yes, I want it to be owned, I just use box so the return type is Sized and the thing that can execute AsRef is there, owned. But I'm ok with a box that lives shortly
The problem is that AsRef gives you a reference to the allocation owned by the box, and that allocation is not tied to the lifetime on the inner type, and cannot live past when the box goes out of scope.
I think this is what I wanted, actually. I do not intend to make the thing inside the box live by itself. The Box is just for storing the dyn. Why I do this? Well, some rust memory allocators like TypedArena give you references anyway, so I just wanted a common interface for using different memory allocators. Returning -> Box<dyn AsRef<[T]> + 'r>; gives the flexibility that I wanted.
I just don't understand why I'm getting that error.
As for why you're getting the error, it boils down to constructing a box that gets dropped at the end of the scope but you still want to have its reference which just cant work.
The problem with your solution is that it only lets me return references. What if I want to really allocate something that lives by itself? For example, I could use TypedArena for allocating a true slice, but I could also want to use an inneficient allocator that just alocates a Vec, which lives by itself. That's why I wanted the Box to contain anything that implement AsRef<[T]>, not just return a slice. Do you think it's possible?
in summary: I want to return a Box of something that implements AsRef<[T]>, but this something could be a slice (short lifetime) or a vec (static lifetime). The second case is for when I need to pass things to other threads, etc. And the lifetime, of course, should be the 'r from DataAllocator
wouldn't it clone the slice allocated by TypedArena, everytime I need to mutate it? (I need to mutate in most of the cases). I cannot afford these clones, that's why I'm using a memory pool. But for some cases I want to relax and use a Vec
If you have a Cow::Borrowed(...), calling Cow::to_mut will turn it into a Cow::Owned(...), allocating a new Vec in the process. After that, if you call Cow::to_mut again on the same value, it'll just give you a mutable reference to the existing Vec, rather than allocating again.
it was meant to be used at compile time. When I know it's a threaded thing, I use the 'static version with vec allocation. When I'm gonna use the type inside the same thread, I use the lifetimed
Then the returned type have to describe these two cases, somehow. Because not only you need to know which version was choosen, compiler needs to know, too.
If Cow is not suitable then you would have to create your own type with appropriate semantic.
But if you return some type which couldn't carry the required information (like Box) compiler would be confused.