【问题标题】:How do I convince the borrow checker that a function call result will not outlive &self如何让借用检查器相信函数调用结果不会超过 &self
【发布时间】:2022-08-20 21:41:03
【问题描述】:

自从发布原始问题以来,我设法将示例归结为:


    trait Bacon {
        fn foo(&mut self, x: usize) -> Result<usize, f32>;
    }

    pub struct Banana<\'a> {
        phantom: PhantomData<&\'a ()>,
    }

    impl<\'a> Banana<\'a> {
        fn inner_foo(&\'a mut self, x: usize) -> Result<usize, Box<dyn Error + \'a>> {
            Ok(x)
        }
    }

    impl<\'a> Bacon for Banana<\'a> {
        fn foo(&mut self, x: usize) -> Result<usize, f32> {
            self.inner_foo(x).map_err(|_| 0.0)
        }
    }

编译器给我以下错误:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> /home/thoth/src/rust-esp32-experiments/http-camera/webcam-applib/src/lib.rs:97:18
   |
97 |             self.inner_foo(x).map_err(|_| 0.0)
   |                  ^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
  --> /home/thoth/src/rust-esp32-experiments/http-camera/webcam-applib/src/lib.rs:96:16
   |
96 |         fn foo(&mut self, x: usize) -> Result<usize, f32> {
   |                ^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> /home/thoth/src/rust-esp32-experiments/http-camera/webcam-applib/src/lib.rs:97:13
   |
97 |             self.inner_foo(x).map_err(|_| 0.0)
   |             ^^^^
note: but, the lifetime must be valid for the lifetime `\'a` as defined here...
  --> /home/thoth/src/rust-esp32-experiments/http-camera/webcam-applib/src/lib.rs:95:10
   |
95 |     impl<\'a> Bacon for Banana<\'a> {
   |          ^^
note: ...so that the types are compatible
  --> /home/thoth/src/rust-esp32-experiments/http-camera/webcam-applib/src/lib.rs:97:18
   |
97 |             self.inner_foo(x).map_err(|_| 0.0)
   |                  ^^^^^^^^^
   = note: expected `&mut Banana<\'_>`
              found `&mut Banana<\'a>`

我认为我的代码是安全的,Box&lt;dyn Error+\'a&gt; 的寿命不会超过&amp;self,但我可能忽略了其他一些生命周期问题。

kmdreko 提到\'a\'_ 更受限制,但我不确定如何修改inner_foo 以捕获Box 内容的生命周期特征。

我尝试将 read_inner 的返回类型更改为 Result&lt;usize, Box&lt;dyn Error + \'static&gt;&gt; ,但这给了我很多错误,并建议我将 \'static\' 添加到 where 子句(ES,EI)的元素中,这将通过调用层次结构。我希望使用 map_err 作为防火墙来避免这种情况。

cargo 1.62.1-nightly (a748cf5a3 2022-06-08)
rustc 1.62.1-nightly (e4f2cf605 2022-07-19)

如何让编译器相信我的代码是安全的?

  • 这是重现问题所需的缺少代码,但您似乎拥有与您的类型 CameraBody 相关联的生命周期 \'a,因此您的 read_inner 自我看起来像:&amp;\'a mut CameraBody&lt;\'a, ...&gt;。问题不在于Box&lt;dyn Error + \'a&gt;,问题是您不能将&amp;mut self 伪装成&amp;\'a mut self,因为后者受到更多限制。
  • 尝试引入不同的生命周期参数read_inner&lt;\'b&gt;(&amp;\'b mut self, ...) -&gt; Result&lt;..., Box&lt;dyn Error + \'b&gt;&gt;
  • 你确定错误真的取决于self 的生命周期吗?我们缺少产生错误的代码,但错误的生命周期似乎更可能不依赖于自身。您可能想改用Box&lt;dyn Error + \'static&gt;

标签: rust borrow-checker


【解决方案1】:

我目前已经解决了这个问题,但没有使用 kmdreko 建议的&lt;'b&gt; 技术解决它。我不得不修改应用程序其余部分的大部分内容以使其工作(并修补指定特征的板条箱),所以最初的问题仍然很有趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2023-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多