我有一段代码在
wgpu
v0.19 版本中运行。现在我尝试将 wgpu
更新到 v22 并收到与生命周期相关的编译错误,但我无法找出原因。
这是代码片段:
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
}
尝试编译此代码时遇到的错误是:
--> 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`
方法
render
定义为:
pub fn render<'a>(
&self,
render_pass: &'a mut wgpu::RenderPass<'a>,
paint_jobs: &[epaint::ClippedPrimitive],
screen_descriptor: &ScreenDescriptor,
) {}
如果我删除上面的
'a
生命周期,我会收到类似的 RenderPass
生命周期错误...
我不明白的是为什么编译器坚持认为
wgpu_frame
必须比 'static
更长寿?这个要求从何而来?我怎样才能减轻这个要求?
以防万一,
begin_render_pass
方法具有以下签名:
pub fn begin_render_pass<'encoder>(
&'encoder mut self,
desc: &RenderPassDescriptor<'_>,
) -> RenderPass<'encoder> {}
这也不需要任何东西来延长
'static
...
我知道我可以通过调用
render_pass.forget_lifetime()
让编译器保持沉默,但我宁愿了解编译器想要从我这里得到什么,而不是让它关闭。
问题就在这里:
render_pass: &'a mut wgpu::RenderPass<'a>,
在 &mut
内部和外部使用
same生命周期参数本质上总是不正确的,因为您施加了同时约束:
'a
'a
借用的东西,因此当 'a
结束时这最终意味着“这是借来的,以维持其自身的存在”,而且它永远不能被丢弃。相反,您应该让生命周期不同,这最容易通过不命名来实现:
render_pass: &mut wgpu::RenderPass<'_>,