関連するタイプを使用しているため、Rust 1.14で生涯エラーが発生しました。次の2つの同様のプログラムによって示されます。生涯エラー。寿命パラメータと関連するタイプの特性を使用した寿命エラー
プログラム#1 - エラー
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a()>;
}
struct Alpha<'a, T: Trait<'a>> {
_dummy: std::marker::PhantomData<(&'a(), T)>,
}
fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {}
fn main() {
for x in Vec::<Alpha<Impl>>::new().into_iter() {
use_alpha(&x); // <-- ok
}
}
プログラム#2なしでコンパイルが -
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a()>;
}
struct Alpha<'a, T: Trait<'a>> {
_dummy: std::marker::PhantomData<(&'a(), T::T)>,
}
fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {}
fn main() {
for x in Vec::<Alpha<Impl>>::new().into_iter() {
use_alpha(&x); // <-- !error!
}
}
寿命の誤差を持っているここで、第2のプログラムは、コンパイル時エラーです:
error: `x` does not live long enough
--> src/main.rs:20:5
|
19 | use_alpha(&x); // <-- !error!
| - borrow occurs here
20 | }
| ^`x` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
は、ここでは、2つのプログラムの差分は次のとおり
#[derive(Clone)]
struct Alpha<'a, T: Trait<'a>> {
- _dummy: std::marker::PhantomData<(&'a(), T)>,
+ _dummy: std::marker::PhantomData<(&'a(), T::T)>,
}
唯一の違いは、最初のプログラムを変更することによって、関連するタイプの代わりにstruct
定義における型パラメータを使用することで、ライフタイムエラーが発生します。なぜこのようなことが起こるのか分かりません。私が知る限り、関連する型には生涯の制限はありません。すべてが'a
ですが、明らかにRustコンパイラには同意できません。
2番目のプログラムのmain
関数の反復を簡単なインスタンス化に置き換えると、生涯エラーがなくなります。つまり、
fn main() {
let x = Alpha::<Impl> { _dummy: std::marker::PhantomData };
use_alpha(&x); // <-- ok in both programs
}
なぜ反復が直接インスタンシエーションと異なるのか分かりません。
私はまだこれを解決しようとしています。しかし、私はあなたが 'into_iter() 'の代わりに' iter() 'を使うことができて、それがうまくいくことを発見しました。 –