2

I'm using the rust-sdl2 crate to paint a buffer on a window screen, so I decided to abstract the SDL calls. I tried to follow this example from the rust-sdl2 repo and my first thought was to create something like this:

pub struct SDLDisplay {
    sdl_context: Sdl,
    video_subsystem: VideoSubsystem,
    canvas: WindowCanvas,
    texture_creator: TextureCreator<sdl2::video::WindowContext>,
    texture: Texture,
}

impl SDLDisplay {
    pub fn new() -> Result<SDLDisplay, String> {
        let sdl_context = sdl2::init()?;
        let video_subsystem = sdl_context.video()?;

        let window = video_subsystem
            .window("Test App", 256, 240)
            .position_centered()
            .build()
            .map_err(|e| e.to_string())?;

        let canvas = window.into_canvas().build().map_err(|e| e.to_string())?;

        let texture_creator = canvas.texture_creator();
        let texture = texture_creator
            .create_texture_streaming(Some(ARGB8888), 256, 240)
            .map_err(|e| e.to_string())?;

        Ok(SDLDisplay {
            sdl_context,
            video_subsystem,
            canvas,
            texture_creator,
            texture,
        })
    }
}

The first issue was that Texture needs a lifetime parameter; I solved that by spreading an <'a> across the code base... It stopped complaining about that, but now I have the following:

error[E0515]: cannot return value referencing local variable `texture_creator`
   |
  --> src/sdl_display.rs:44:9
40 |           let texture = texture_creator
   |                         --------------- `texture_creator` is borrowed here
   |
...
40 |           let texture = texture_creator
44 | /         Ok(SDLDisplay {
   |                         --------------- `texture_creator` is borrowed here
45 | |             sdl_context,
...
46 | |             video_subsystem,
44 | /         Ok(SDLDisplay {
47 | |             canvas,
45 | |             sdl_context,
48 | |             texture_creator,
46 | |             video_subsystem,
49 | |             texture,
47 | |             canvas,
48 | |             texture_creator,
49 | |             texture,
50 | |         })
   | |__________^ returns a value referencing data owned by the current function

50 | |         })
   | |__________^ returns a value referencing data owned by the current function

It's telling me I can't move texture_creator to the new struct because it was borrowed for creating the texture, but if I don't have the TextureCreator instance inside the struct, it complains that Texture must not outlive TextureCreator.

I'm completely lost here. Is there a way to actually store a texture inside a struct using rust-sdl2?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
dospro
  • 450
  • 1
  • 5
  • 17
  • I believe your question is answered by the answers of [Cannot infer an appropriate lifetime for autoref due to conflicting requirements](https://stackoverflow.com/q/41270052/155423) and [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/q/32300132/155423). If you disagree, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster May 09 '19 at 03:49
  • *I solved that by spreading an `<'a>` across the code base* — the code you have presented has no `<'a>` in it. Are you asking about errors that come from code that you haven't even provided? – Shepmaster May 09 '19 at 03:52
  • @Shepmaster yes. those other answers provide enough info to answer this question. I couldn't see how was a value and a reference for something inside the value what was happening here. For the second comment: I thought pasting basically the same code with only lifetime changes would bloat the question. – dospro May 09 '19 at 05:11

0 Answers0