#Forcing lifetime error

31 messages · Page 1 of 1 (latest)

eternal marlin
meager cape
#
    impl<T: Deref> Deref for Guard<T> {
        type Target = T::Target;

        fn deref(&self) -> &T::Target {
            &*self.value
        }
    }
#

note that this changes the result of Deref from being &&str to &str

#

but this has the effect you want because it disregards the 'static ness of T = &'static str, and just takes a (short-lived as per the signature of Deref) reference to the str inside of it

eternal marlin
#

Hmm, one issue, if T is &'static &'static str, then it compiles.

fn main() {
    use guard::Guard;

    let static_static_str: &'static &'static str = &"12345";
    let x = Guard::new(static_static_str);
    let y: &str = &x[0..1];
    drop(x);
    dbg!(y.len());
}
meager cape
#

there isn't really any way to stop that

#

given that you want to accept an arbitrary T

#

an arbitrary T can be all sorts of things

#

some of them don't even deref to the value but grant access to it anyway, like for example &fn() -> &'static str

#

what's the purpose of this restriction?

eternal marlin
#

I have an "owned slice" (like Box<[u8]>) that deallocates (calls a C function that manages the object) when it's dropped. I need Guard to hold both the value and the owned slice, and to assure that whenever the owned slice is dropped, the value is dropped as well, as it might hold references to the slice

meager cape
#

sorry, what's "the value" here? can you show in code?

eternal marlin
#

well, that's the owned slice

#

the value would be something like struct Something<'a>(&'a str)

#

and say the str is std::str::from_utf8(&owned_slice)

meager cape
#

okay, so, the normal way things like this work is that the 'a lifetime is the lifetime of the borrow of the owned slice

#

and that is completely, by itself, sufficient to ensure dropping in the right order

#

this should all happen automatically when you write std::str::from_utf8(&owned_slice)

#

you shouldn't have a problem unless you're using unsafe code to muck with lifetimes

eternal marlin
#

The main problem is that I can't return both the Something and DBPinnableSlice from my function, so I have to return DBPinnableSlice and call from_utf8 whenever it's used, repeating work

meager cape
#

ok, so you have the 'self-referential struct' problem

#

that is, you want a struct or whatever that you can return that contains the owned data and a reference to it

#

you can solve that by itself

#

https://docs.rs/yoke/ is also recently popular but it is still getting the bugs worked out, from what I've heard

#

I believe it's also possible to do this using Rust's built-in Pin mechanism (+ helpers like https://docs.rs/pin-project) but that's generally less ergonomic and may have more restrictions

eternal marlin
#

Interesting, thank you, I'll try one (or more) of these out

meager cape
#

an important thing to note is that neither the borrow nor the owned thing need to know about what you're trying to do

#

rather, you as the creator of the special combined struct set them up, using their regular, safe, public interfaces