#Dangling reference

37 messages · Page 1 of 1 (latest)

keen valley
#

So I have this editor module:

// <... imports ...>

pub struct Editor<'a> {
    render_manager: RenderManager<'a>,
    font_manager: FontManager,
}

impl<'a> Editor<'a> {
    pub fn new (window: Window) -> Self {
        let renderer = window.into_canvas().build().unwrap();

        Editor {
            render_manager: RenderManager::new(renderer),
            font_manager: FontManager::new(),
        }
    }

    pub fn show_window (&mut self) { self.render_manager.show_window(); }
    pub fn render_all_views (&mut self) { self.render_manager.render_all_views(); }
}

And inside of it, I create a new RenderManager:

// <... imports ...>

const BACKGROUND_COLOR: Color = Color::RGB(46, 46, 50);

pub struct RenderManager<'a> {
    renderer: WindowCanvas,

    // -- for rendering fonts --
    font_texture: FontTexture<'a>,
    text_layout: Layout<Color>
}

impl<'a> RenderManager<'a> {
    pub fn new (renderer: WindowCanvas) -> Self {
        let texture_creator = renderer.texture_creator();
        let font_texture = FontTexture::new(&texture_creator).unwrap();
        
        RenderManager { 
            renderer, 
            font_texture, 
            text_layout: Layout::new(CoordinateSystem::PositiveYDown) 
        }
    }

    pub fn show_window (&mut self) {
        self.renderer.window_mut().show();
    } 

    fn clear_all_views (&mut self) {
        self.renderer.set_draw_color(BACKGROUND_COLOR);
        self.renderer.clear();
    }

    pub fn render_all_views (&mut self) {
        self.clear_all_views();
        self.renderer.present();
    }
}

I believe that the issue is that in the RenderManager impl, in the new function, the texture_creator only exists during the function, so when we return the RenderManager it would be a dangling reference, but I don't know how to fix this...

keen valley
#

oh and here's the actual error:

   Compiling ducky v0.1.0 (D:\Code\ducky)
error[E0515]: cannot return value referencing local variable `texture_creator`                                                                                                                                                                                        
  --> src\editor\render_manager.rs:20:9
   |
18 |           let font_texture = FontTexture::new(&texture_creator).unwrap();
   |                                               ---------------- `texture_creator` is borrowed here
19 |           
20 | /         RenderManager { 
21 | |             renderer, 
22 | |             font_texture, 
23 | |             text_layout: Layout::new(CoordinateSystem::PositiveYDown) 
24 | |         }
   | |_________^ returns a value referencing data owned by the current function

For more information about this error, try `rustc --explain E0515`.                                                                                                                                                                                                   
error: could not compile `ducky` (bin "ducky") due to 1 previous error
lofty patio
#

can you make FontTexture be able to take ownership instead of needing a reference?

keen valley
#

oh wait i just realised that i removed the imports to shorten the message. actually FontTexture is from a crate, so idk if i can change it’s code

#

lemme also send the imports rq

#

editor.rs

mod font_manager;
mod render_manager;

use sdl2::video::Window;
use font_manager::FontManager;
use render_manager::RenderManager;

render_manager.rs

use fontdue::layout::{CoordinateSystem, Layout};
use fontdue_sdl2::FontTexture;
use sdl2::{pixels::Color, render::{TextureCreator, WindowCanvas}, video::WindowContext};
weak echo
#

use the unsafe_textures features in sdl2 and its crates

keen valley
#

so if I use unsafe_textures, I could free the memory manually, or it would automatically get freed when the last Canvas or TextureCreator will be freed?

weak echo
#

Yes

#

Personally I would just leave everything alive, unless you are constantly generating new textures

keen valley
#

ok

#

but, wait, how would this be a lifetime issue?

#

well, ig it's a lifetime issue, but for the texture_creator and font_texture

#

like how would textures no longer having a lifetime change anything?

weak echo
#

it should remove the requirement for the lifetime that is causing the error

#

FontTexture would no longer have a lifetime and thus no longer be dangling

keen valley
#

but isn't the dangling caused by font_texture needing a reference to texture_creator?

weak echo
#

Yes

#

And the reason it needs a reference to texture_creator is because it creates a texture that needs that reference

#

So, if you remove the reference from Texture, you remove the reference from FontTexture

keen valley
#

here's a piece of code from the public_api_no_lifetime.rs file of the fontdue-sdl2 crate im using:

pub struct FontTexture {
    pub texture: Texture,
    rect_allocator: RectAllocator,
}

impl FontTexture {
    pub fn new<T>(texture_creator: &TextureCreator<T>) -> Result<FontTexture, String> {
        let texture = crate::create_font_texture(texture_creator)?;
        let rect_allocator = RectAllocator::new(1024, 1024);
        Ok(FontTexture {
            texture,
            rect_allocator,
        })
    }
    // ....
}
#

it would still need a reference, no matter lifetime or no lifetime

weak echo
#

If you don't get what I'm saying then just try it

keen valley
#

okay, so do I just enable unsafe_textures in sdl2?

weak echo
#

It will tell you to remove the lifetime from FontTexture and then from RenderManager

#

and then it will just work TM

weak echo
keen valley
#

wait this actually works

#

but why?

weak echo
#

You remove the lifetime constraint that causes the failing check

#

RenderManager no longer needs to check that the TextureCreator stays alive

keen valley
#

ohhh i get it now

#

thanks so much man

#

should I like close this post, since it's solved?

weak echo
#

🤷‍♂️

#

The problem you had common and annoying enough that sdl2-rs introduced this feature as essentially just a magic fix