为什么 rustc 的建议在这里是错误的?



我正在尝试实现以下特性,其中<'baz>是以后的impl<'baz> Baz<'baz> for T where T: OtherTrait所必需的。

trait Baz<'baz>: Clone {
fn baz(&'baz mut self);

fn bazzed(&self) -> Self {
let mut x = self.clone();
x.baz();
x
}
}

Rustc失败是可以理解的:

Compiling playground v0.0.1 (/playground)
error[E0309]: the parameter type `Self` may not live long enough
--> src/lib.rs:6:9
|
6 |         x.baz();
|         ^
|
= help: consider adding an explicit lifetime bound `Self: 'baz`...
= note: ...so that the type `Self` is not borrowed for too long
error[E0309]: the parameter type `Self` may not live long enough
--> src/lib.rs:6:11
|
6 |         x.baz();
|           ^^^
|
= help: consider adding an explicit lifetime bound `Self: 'baz`...
= note: ...so that the reference type `&'baz mut Self` does not outlive the data it points at
For more information about this error, try `rustc --explain E0309`.
error: could not compile `playground` due to 2 previous errors

所以我遵循它的建议:

trait Baz<'baz>: Clone {
fn baz(&'baz mut self);

fn bazzed(&self) -> Self 
where
Self: 'baz
{
let mut x = self.clone();
x.baz();
x
}
}

我不太明白它现在不喜欢什么。。。

Compiling playground v0.0.1 (/playground)
error[E0597]: `x` does not live long enough
--> src/lib.rs:9:9
|
1  | trait Baz<'baz>: Clone {
|           ---- lifetime `'baz` defined here
...
9  |         x.baz();
|         ^^^^^^^
|         |
|         borrowed value does not live long enough
|         argument requires that `x` is borrowed for `'baz`
10 |         x
11 |     }
|     - `x` dropped here while still borrowed
error[E0505]: cannot move out of `x` because it is borrowed
--> src/lib.rs:10:9
|
1  | trait Baz<'baz>: Clone {
|           ---- lifetime `'baz` defined here
...
9  |         x.baz();
|         -------
|         |
|         borrow of `x` occurs here
|         argument requires that `x` is borrowed for `'baz`
10 |         x
|         ^ move out of `x` occurs here
Some errors have detailed explanations: E0505, E0597.
For more information about an error, try `rustc --explain E0505`.
error: could not compile `playground` due to 2 previous errors

我也试着制作Self: 'static,但也无济于事。我在这里错过了什么?



<'baz>我需要另一个特征,大致看起来像:

trait ReturnIteratorMut<'item> {
type IterType: Iterator<Item = &'item mut Thing>;
fn iterator<'slf: 'item>(&'slf mut self) -> Self::IterType;
}

我想通过将baz()应用于迭代器中的每个项来实现所有这些的Baz,所以我需要'baz: 'item。这只适用于baz()方法,它只开始抱怨bazzed()

让我们首先尝试在没有编译器帮助的情况下理解此代码的错误。

x.baz()需要x'baz而活。由于'baz可以是任何寿命,这意味着x必须为'static而活。它不是——它是一个局部变量,这是一个错误(你可能想要HRTB,但你说你想专注于编译器错误,所以我不处理解决方案)。

编译器的第二个错误只是x的寿命不够长,或者,如果我们从相反的角度来看,x是为'static借用的,因此我们无法移动它(编译器显示这两个错误是为了最大限度地显示错误-有时它有效,有时,就像本例中一样,它会导致显示令人困惑的错误)。

第一个错误是这个约束的一个可以忽略的结果,但它隐藏了实际的错误(值得一提的是,在夜间,它们都显示在一起):x需要为'static生存,但不仅如此,有时它类型的任何变量都不可能是。假设Self&'some_short_lifetime i32,它不能为'static生存,因为它包含更短的生存期。这就是为什么";Self可能活得不够长。

相关内容

  • 没有找到相关文章

最新更新