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
:
use std::marker::PhantomData;
pub struct Data<'a, T>{
a: &'a [T]
}
impl<'a, T> Data<'a, T> {
pub fn new() -> Data<'a, T> {
todo!()
}
fn iter(&'a self) -> Iter<'a, T> {
todo!()
}
}
pub struct Iter<'a, T> {
_phantom: PhantomData<&'a T>
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
pub trait DataAllocator<'s, 'r, T> {
fn allocate(&'s self) -> Box<dyn AsRef<[T]> + 'r>;
}
impl<'s, 'r, T> DataAllocator<'s, 'r, T> for Data<'r, T> {
fn allocate(&'s self) -> Box<dyn AsRef<[T]> + 'r> {
todo!()
}
}
fn do_something<'a, 'b, T>(data_allocator: &'a dyn DataAllocator<'a, 'b, T>) -> Data<'b, T> {
let buffer = data_allocator.allocate();
let data = Data{a: (*buffer).as_ref()};
for e in data.iter(){}
data
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2a3e0d0cdea86238413af25dddd04e19
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?
I think the confusion is getting .as_ref()
on a dyn AsRef<[T]> + 'r
returns a reference tied to itself, not to the 'r
lifetime. So the reference you get from (*buffer).as_ref()
is derived from buffer
, which of course goes out of scope.
Its hard to say what you should do about it though, since the todo!()
s obscure how you were planning to accomplish this. But based on what I see, I would probably expect the allocate()
to return a &'r [T]
. Playground.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With