Search code examples
rustwgpu-rs

Lifetime issue of wgpu RenderPass after updating to v22.0


I have a piece of code that was working in the version of wgpu v0.19. Now I try to update wgpu to v22 and get a compilation error related to lifetimes that I cannot figure out the reason for.

Here is the code snippet:

    pub fn render(&mut self, wgpu_frame: &mut WgpuFrame, run_ui: impl FnMut(&Context)) {
        // some unrelated stuff

        {
            let mut render_pass =
                wgpu_frame
                    .encoder
                    .begin_render_pass(&wgpu::RenderPassDescriptor {
                        color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                            view: wgpu_frame.texture_view,
                            resolve_target: None,
                            ops: wgpu::Operations {
                                load: wgpu::LoadOp::Load,
                                store: wgpu::StoreOp::Store,
                            },
                        })],
                        depth_stencil_attachment: None,
                        label: Some("egui render pass"),
                        timestamp_writes: None,
                        occlusion_query_set: None,
                    });

            self.renderer
                .render(&mut render_pass, &paint_jobs, &screen_descriptor);
        }

        // a little more unrelated stuff
    }

The error I'm getting when trying to compile this code is:

   --> galileo/examples/with_egui/src/state/egui_state.rs:93:17
    |
59  |       pub fn render(&mut self, wgpu_frame: &mut WgpuFrame, run_ui: impl FnMut(&Context)) {
    |                                ----------  - let's call the lifetime of this reference `'1`
    |                                |
    |                                `wgpu_frame` is a reference that is only valid in the method body
...
93  | /                 wgpu_frame
94  | |                     .encoder
95  | |                     .begin_render_pass(&wgpu::RenderPassDescriptor {
96  | |                         color_attachments: &[Some(wgpu::RenderPassColorAttachment {
...   |
107 | |                         occlusion_query_set: None,
108 | |                     });
    | |                      ^
    | |                      |
    | |______________________`wgpu_frame` escapes the method body here
    |                        argument requires that `'1` must outlive `'static`

The method render is defined as:

    pub fn render<'a>(
        &self,
        render_pass: &'a mut wgpu::RenderPass<'a>,
        paint_jobs: &[epaint::ClippedPrimitive],
        screen_descriptor: &ScreenDescriptor,
    ) {}

If I remove 'a lifetime above, I get a similar error for lifetime of RenderPass...

What I cannot figure out is why the compiler insists that wgpu_frame must outlive 'static? Where this requirement comes from? And how I can alleviate this requirement?

Just in case, the begin_render_pass method has this signature:

    pub fn begin_render_pass<'encoder>(
        &'encoder mut self,
        desc: &RenderPassDescriptor<'_>,
    ) -> RenderPass<'encoder> {}

Which also doesn't require anything to outlive 'static...

I know I can silence the compiler by calling render_pass.forget_lifetime(), but I'd rather understand what the compiler wants from me rather than making it shut up.


Solution

  • It turns out that I was looking in the wrong place for the solution. The original version of the render function from egui-wgpu crate required RenderPass to have static lifetime. But I modified it in the cargo git cache for tests and it didn't change anything, so I assumed it's not the issue. But it turns out that cargo cannot detect changes in the dependencies that are not in the current project folder, so to apply those changes I would first have to do cargo clean, which would show that removing that requirement from the RenderPass does solve the issue (but creates another one...)

    I've checked what Kevin Reid suggested, but it turns out that those lifetimes are not an issue and do not produce any compiler error (at least in this case).