#Rust help requested. I am officially at wits end here.

Please take a look at my source file sdlstate.rs.

I'm getting a borrow checker error E0597 on line 39, indicating that tc does not live long enough. However, looking at the sdl2 sources (via its rust-docs), I don't see how my created texture, t, can possibly still refer to tc, which as far as I'm aware, is the only way this error can be generated under current conditions.

error[E0597]: `tc` does not live long enough
--> src/sdlstate.rs:39:21
14 | impl<'a> SdlState<'a> {
| -- lifetime `'a` defined here
39 | let mut t = tc
| _____________________^
40 | | .create_texture(
41 | | Some(sdl2::pixels::PixelFormatEnum::RGBA8888),
42 | | sdl2::render::TextureAccess::Streaming,
43 | | self.width,
44 | | self.height,
45 | | )
| |_____________^ borrowed value does not live long enough
49 | self.current_texture.set(Some(t));
| --------------------------------- argument requires that `tc` is borrowed for `'a`
56 | }
| - `tc` dropped here while still borrowed

Why is this happening? Why can't I re-arrange the code to prevent this from happening?

Right now, the only way this code will compile and run correctly is if I manually inject the re-paint code where I invoke f(), which utterly defeats the purpose and benefit of using closures in the first place.

In an attempt to fix this, I've tried:

Replacing the Cell with RefCell.
Removing Cell all-together and just using a raw Option type.
Removing the 'a lifetime annotation.

None of these work, and almost always introduce some manner of errors on their own.

Please help. Thanks.

@vertigo `t` is referencing `tc`, look at the `create_texture` function signature.
You need to store `tc` for a time >= `t`.

You are probably going to end up with a self-referential struct:
The field `self.t` will need to reference `self.tc`.
It's a bit hard, but it will solve your problem.

To get self-referential structs working, see this SO question stackoverflow.com/questions/32

@ranfdev I've looked at the signatures and the structs themselves, and I'm not finding where this reference is happening.

From another discussion on this topic, it looks like I might have misunderstood how lifetime annotations work; but, even after reevaluating structure lifetimes, I'm still not seeing why I'm getting the error.

I'll check the link you provided as soon as I'm in front of a computer again, thanks for the link. Hoping it will shed some light on my woes.

@vertigo `create_texture` takes `&self, ...` and returns a `Result<Texture<'_>,...>`

The lifetime `'_` refers to the lifetime of the only reference available, so `&self`.
In this case you can imagine `&self == &'_ self`

That means `t` is referencing `&tc`.

@ranfdev Right; but I can show in my code that tc out-lives t. What I can't get is why Rust doesn't think this is the case.

@vertigo in the code you posted, tc is _not_ outliving t. Tc gets dropped at the end of the function, while t keeps living inside the struct.

Rust sometimes is over aggressive, but not in this case.

The sdl2 crate authors designed the API in this way and rust is simply enforcing it, correctly

@ranfdev No; look after the call to the closure, where I take() the value of t again, and use it to clean up the texture. I fully expect t to be dropped at the end of the function, not to out-live it.


@vertigo Ah, I see...
You are right, t gets dropped at the end of the function

But rust doesn't care what you do with t after line 49. In 49 you are breaking the lifetimes guarantees, and that will trigger the error.

I can see the disappointment.

Sign in to participate in the conversation

Linux geeks doing what Linux geeks do...