Borrow of `video_subsystem` occurs here

I'm trying to make something with SDL2 but it says all of this:

let video_subsystem: VideoSubsystem

---

engine_audio::graphics::Graphics

video_subsystem: VideoSubsystem

Go to VideoSubsystem

cannot return value referencing local variable `video_subsystem`
returns a value referencing data owned by the current function

graphics.rs(29, 23): `video_subsystem` is borrowed here

cannot move out of `video_subsystem` because it is borrowed
move out of `video_subsystem` occurs here rustc[E0505](https://doc.rust-lang.org/error-index.html#E0505)

graphics.rs(29, 23): borrow of `video_subsystem` occurs here

graphics.rs(25, 23): let's call the lifetime of this reference `'1`

graphics.rs(45, 16): returning this value requires that `video_subsystem` is borrowed for `'1`

How can I fix this? This is the code:


pub struct Graphics<'a> {
    pub title: &'a str,
    pub window_size: [i32; 2],
    pub max_fps: u32,

    sdl_context: sdl2::Sdl,
    video_subsystem: sdl2::VideoSubsystem,
    window: Window,
    gl_attr: GLAttr<'a>,
    ctx: GLContext
}

impl Graphics<'_> {
    pub fn new(title: &str, window_size: [i32; 2], max_fps: u32, gl_context_version: (u8, u8)) -> Graphics {
        let sdl_context = sdl2::init().unwrap();
        let video_subsystem = sdl_context.video().unwrap();

        let gl_attr = video_subsystem.gl_attr();
        gl_attr.set_context_profile(GLProfile::Core);
        gl_attr.set_context_version(gl_context_version.0, gl_context_version.1);

        let window = video_subsystem.window(title, window_size[0] as u32, window_size[1] as u32)
            .position_centered()
            .opengl()
            .build()
            .unwrap();
        
        let ctx = window.gl_create_context().unwrap();
        gl::load_with(|name| video_subsystem.gl_get_proc_address(name) as *const _);

        debug_assert_eq!(gl_attr.context_profile(), GLProfile::Core);
        debug_assert_eq!(gl_attr.context_version(), gl_context_version);

        return Graphics {
            title,
            window_size,
            max_fps,

            sdl_context,
            video_subsystem,
            window,
            gl_attr,
            ctx
        };
    }

    pub fn start_loop(&self) {
        let mut event_pump = self.sdl_context.event_pump().unwrap();

        'running: loop {

            unsafe {
                gl::ClearColor(0.6, 0.0, 0.9, 1.0);
                gl::Clear(gl::COLOR_BUFFER_BIT);
            }

            self.window.gl_swap_window();
            for event in event_pump.poll_iter() {
                match event {
                    Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                        break 'running;
                    },

                    _ => {}
                }
            }

            std::thread::sleep(Duration::new(0, 1_000_000_000u32 / self.max_fps));

        }
    }

I'm guessing the errors are from your editor? Try running cargo check in a terminal (and sharing the output); the direct error output may be more clear.

This is because you're trying to store GlAttr in your struct, and that borrows from VideoSubsystem - in other words, you have a self-referential struct.

There's not really any reason to store GlAttr - it's just a wrapper for the SDL2 functions that give you access to the GL attributes, and you can always get it via self.video_subsystem.gl_attr() if you need it again. So I would recommend just removing that field entirely.

1 Like