0

I am writing a graphical program in Rust using the sdl2 crate from crates.io.

I have created this struct in main.rs:

struct GameObject {
    name: &'static str,
    pub texture: Option<Texture<'static>>
}

impl GameObject {
    pub fn new(name: &'static str) -> Self {
        Self { name, texture: None }
    }

    pub fn set_texture(&mut self, t: Option<Texture<'static>>) {
        self.texture = t;
    }
}

I am trying to add a texture to an instance of GameObject with the following lines of code (where canvas is the result of window.into_canvas().build().unwrap() on my main window):

let tc = canvas.texture_creator();
let mut g = GameObject::new("obj");
g.texture = Some(tc.load_texture("image.png").unwrap());

which causes this error:

error[E0597]: `tc` does not live long enough
  --> src/main.rs:30:22
   |
30 |     g.texture = Some(tc.load_texture("image.png").unwrap());
   |                      ^^---------------------------
   |                      |
   |                      borrowed value does not live long enough
   |                      argument requires that `tc` is borrowed for `'static`

What does this mean in the context of my program?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 1
    Welcome to Stack Overflow! It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Feb 12 '20 at 20:37
  • Why do you believe that the result of `load_texture` has the `'static` lifetime? – Shepmaster Feb 12 '20 at 20:38
  • @Shepmaster a `Texture` requires a lifetime and I didn't see any reason not to make it `'static` for now. either way, giving `GameObject` a lifetime and making its `texture` member match it doesn't change the error – alex franczyk Feb 12 '20 at 20:58
  • Why `Some(x.unwrap())` and not just `x` or `x.ok()`? – Brandon Dyer Feb 12 '20 at 21:07
  • 1
    It looks like your question might be answered by the answers of [Why doesn't a 'static function argument make something live for the entire program?](https://stackoverflow.com/q/42719580/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Feb 12 '20 at 21:25
  • @BrandonDyer i wasn't aware `Result`s could become `Option`s with `ok`, thanks for letting me know – alex franczyk Feb 13 '20 at 00:14

1 Answers1

1

Welcome to stack-overflow community.

Code with comments

To understand error you need to know what 'static lifetime is.

A 'static lifetime is the longest possible lifetime, and lasts for the lifetime of the running program.
A 'static lifetime may also be coerced to a shorter lifetime.

So your example with comments:

// create a `tc` vriable with local lifetime 'a
let tc = canvas.texture_creator();

// "obj" has a static lifetime , and g has a local lifetime 'b
let mut g = GameObject::new("obj"); 

// here you try to put a variable with lifetime 'c (returned by load_texture 
// that is probably equal to 'a) into a variable `g.texture` that is declared
// to contain `'static` lifetime 
// lifetime of "image.png" is `'static` on input of `load_texture()` function 
// but could be shorter in implementation.
g.texture = Some(tc.load_texture("image.png").unwrap()); 

To make it work you could try use lazy-static to declare Texture with 'static lifetime.


Ask cargo to explain

If you see a compiler error - you can always ask cargo to explain it to you with cmd:

cargo --explain E0597

Other similar questions with answers:

S.R
  • 2,411
  • 1
  • 22
  • 33