Closed MarkSwanson closed 7 years ago
I can replicate the problem using your simple_ref.rs test with the following mods:
1. Give Foo a lifetime
2. do not use deref_suffix
pub struct Foo<'a> {
i: i32,
}
#[rental]
pub struct SimpleRef {
foo: Box<Foo>,
iref: &'foo i32,
}
Try to get back a &Foo using ref_rent()
The problem seems to be the life time on Foo<'a>.
Ok, I found the lt_params.rs example, so that explains the Foo<'a>.
I'm still stuck working through my problem. Maybe I need another prefix container...
ref_rent
is for reborrowing references tied to a rental lifetime, but this will only work if the TARGET of the reference does NOT contain any rental lifetimes. You can't do what you're trying to do because point
contains the rental lifetime 'segment
in its type signature. Use of ref_rent
is relatively rare, and it's probably not what you want here.
I've modified your string.rs test to show the problem:
rental! {
pub mod rent_string {
#[rental]
pub struct OwnedStr {
buffer: String,
slice: &'buffer str,
}
}
}
#[test]
fn read() {
let buf = "Hello, World!".to_string();
let rbuf = rent_string::OwnedStr::new(buf, |slice| slice);
assert_eq!(&*rbuf, "Hello, World!");
}
Question: how would this work without deref_suffix ?
Question: I notice in your tests/generic.rs you assign Foo to be generic over the 'static lifetime.
It seems ... like this isn't the case for any real program right? Because no real program would place Foo in the 'static lifetime???
deref_suffix
uses ref_rent
internally to implement it. For the string example, just do:
assert_eq!(rbuf.ref_rent(|suffix| &**suffix), "Hello, World!");
As for the static bound in the generics test, that's a current limitation of rust. I can't lift that bound until rust gets the 'unsafe
lifetime.
So... it seems like I have no way to do what I need to do. I simply want to get a &str by calling point.name() (the returned string would have the same lifetime as the rental struct (or, the same lifetime as 'point) (the same way the string.rs example returns a &str)
Ideas?
Maybe I can just transmute the string I get back to have the same lifetime as the rental struct?
Wrt the TARGET lifetime, the string.rs example has a TARGET of a reference that has a rental lifetime ('buffer).
let s = rbuf.ref_rent(|suffix| &**suffix);
s has a 'buffer lifetime (right? defined in slice: &'buffer str) ?
You can do what you're trying to do:
let name = my_rental.ref_rent(|point| point.name())
And no, the rental lifetime is only attached to the reference itself. We reborrow the reference into another reference with a shorter lifetime. When I say the target of the reference, I mean the Deref::Target
type, which in this case is simply str
. str
has no lifetime parameters at all and is therefore 'static
.
That works! Brilliant!
My problem was that I was trying to get the closure to return a reference to point, and then get the name outside the closure.
Thanks for explaining about str and 'static - I was incorrectly reading that the whole time.
I'm using rent() just fine, but I can't figure out how to use ref_rent()...
*ref_rent() fails: let point: &point::Reader = rent_context.rent(|point| point);
Error messages: the lifetime cannot outlive the lifetime 'segment the lifetime must be valid for the static lifetime...
How would I meet the lifetime requirements?
Do I need to create something like this:
and use point_ref ?
I must still be doing something wrong because there are still 'static lifetime problems (and other lifetime problems)
Thanks!