Borrow of `video_subsystem` occurs here

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

let video_subsystem: VideoSubsystem



video_subsystem: VideoSubsystem

Go to VideoSubsystem

cannot return value referencing local variable `video_subsystem`
returns a value referencing data owned by the current function, 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](, 23): borrow of `video_subsystem` occurs here, 23): let's call the lifetime of this reference `'1`, 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 =;

        let gl_attr = video_subsystem.gl_attr();
        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)
        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 {


    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);

            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

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.