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