0
votes

So, I've been going through the Handmade Hero video series, and I thought it would be an interesting exercise to translate the code into rust. However, I've never really had to deal with lifetimes before, and now I'm getting compile errors related to them. I currently have the following code:

struct TextureData<'a> {
    texture: Texture<'a>,
    width: usize,
    height: usize,
    bytes_per_pixel: usize,
    pixels: Vec<u8>
}

impl TextureData<'_> {
    fn new(texture: Texture, width: usize, height: usize) -> Self {
        TextureData { texture, width, height, bytes_per_pixel: PIXEL_BYTES, pixels: Vec::new() }
    }

    fn fill_texture(&mut self) {
        let size = self.width * self.height * self.bytes_per_pixel;
        let mut pixels: Vec<u8> = Vec::with_capacity(size);
        for i in 0..(self.width * self.height){
            let x = i / self.width;
            let y = i % self.height;
            pixels.push((x % 0xff) as u8);
            pixels.push((y % 0xff) as u8);
            pixels.push(0);
            pixels.push(0);
        }

        self.pixels = pixels;
    }

    fn update(&mut self) {
        let pitch = self.width * self.bytes_per_pixel;
        self.texture.update(None, &self.pixels, pitch);
    }
}

and I am receiving the following feedback:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/main.rs:21:2
   |
21 |     TextureData { texture, width, height, bytes_per_pixel: PIXEL_BYTES, pixels: Vec::new() }
   |     ^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 20:5...
  --> src/main.rs:20:5
   |
20 | /     fn new(texture: Texture, width: usize, height: usize) -> Self {
21 | |     TextureData { texture, width, height, bytes_per_pixel: PIXEL_BYTES, pixels: Vec::new() }
22 | |     }
   | |_____^
note: ...so that the expression is assignable
  --> src/main.rs:21:16
   |
21 |     TextureData { texture, width, height, bytes_per_pixel: PIXEL_BYTES, pixels: Vec::new() }
   |                   ^^^^^^^
   = note: expected  `sdl2::render::Texture<'_>`
              found  `sdl2::render::Texture<'_>`
note: but, the lifetime must be valid for the lifetime `'_` as defined on the impl at 19:18...
  --> src/main.rs:19:18
   |
19 | impl TextureData<'_> {
   |                  ^^
note: ...so that the expression is assignable
  --> src/main.rs:21:2
   |
21 |     TextureData { texture, width, height, bytes_per_pixel: PIXEL_BYTES, pixels: Vec::new() }
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected  `TextureData<'_>`
              found  `TextureData<'_>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.

I have, of course, read the docs for E0495, but I have no idea how it applies in this instance.

1

1 Answers

0
votes

You need to repeat it similarly to how you did when you declared the TextureData struct:

impl<'a> TextureData<'a> {
    fn new(texture: Texture<'a>, width: usize, height: usize) -> Self {
        ...
    }

    ...
}

Note the 3 <'a> added. It doesn't have to be 'a, it could equally be 'b in those 3 places.

Alternatively, if you want to use the "anonymous lifetime" form, then you need to write it like this.

impl TextureData<'_> {
    fn new(texture: Texture<'_>, width: usize, height: usize) -> TextureData<'_> {
        ...
    }

    ...
}