#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 The `TextureCreator` is tied to the `Canvas`, and the textures it returns are tied to the `TextureCreator` (https://docs.rs/sdl2/latest/sdl2/render/struct.TextureCreator.html#method.create_texture, notice the `'_` lifetime)
this means that the struct is self-referential (i.e. one field is a reference to another), which don't work in Rust
@elomatreb I'm not following.
@vertigo The 'a lifetime in your struct wants to be the lifetime of the `Canvas`. Do you see why the `TextureCreator` and its `Textures` are tied to each other?
The 'a lifetime in your struct wants to be the lifetime of the Canvas.
I thought that the 'a was there to indicate that the current_texture lifetime would at least be as long as the SdlState structure's lifetime.
Do you see why the TextureCreator and its Textures are tied to each other?
No, I don't. According to https://docs.rs/sdl2/latest/src/sdl2/render.rs.html#664-667 and https://docs.rs/sdl2/latest/src/sdl2/render.rs.html#1655-1657, there does not appear to be any relationship between them. I'm not sure where Rust is inferring a relationship from.
@vertigo That understanding of lifetime annotations is the wrong way around. They indicate that a struct annotated with one contains a reference to something else outside of itself, which naturally implies that the struct itself can only be valid as long as the thing it references is valid.
The types are tied to each other like this: `TextureCreator` is tied to the `Canvas`/the `Window` it contains because the definition of this method: https://docs.rs/sdl2/latest/sdl2/render/struct.Canvas.html#method.texture_creator - notice how it carried along the `'s` lifetime annotation. In turn then the `Texture`s are tied to the `TextureCreator` because of the definition of the definition of this method: https://docs.rs/sdl2/latest/sdl2/render/struct.TextureCreator.html#method.create_texture - The `'_` thing in the return type is a shorthand for reusing the lifetime of a single input reference, i.e. the one of `&self` in this case
@elomatreb Yes. That's the intention. But, inside the closure, there will be any number of calls to paste_stamp_be() or similar functions which draws directly into the texture.
I do not want to have to explicitly pass a texture argument for every time I call something to draw. So, I wanted to store the texture for future reference other methods.