error[E0282]: type annotations needed for `Xxx`

型推論が失敗した場合について。

他エラーとの関係

このエラーは『E0284 - 型推論の失敗 - 2』と原理や対策が共通している。

パターン

パターン A

基本形

型推論のための情報が不足しているパターン。

サンプル


fn main() {
    let val = MyType(None);
    assert!(val.0.is_none());
}

struct MyType<T>(Option<T>);

error[E0282]: type annotations needed for `MyType<_>`
 --> src\main.rs:2:9
  |
2 |     let val = MyType(None);
  |         ^^^            ---- type must be known at this point
  |
help: consider giving `val` an explicit type, where the type for type parameter `T` is specified
  |
2 |     let val: MyType<T> = MyType(None);
  |            +++++++++++

解決策 1

エラーメッセージにもあるが、変数宣言で型を明示すればよい。


fn main() {
    let val: MyType<i32> = MyType(None);
    assert!(val.0.is_none());
}

struct MyType<T>(Option<T>);

解決策 2

値の生成時に型を明示する方法もある。


fn main() {
    let val = MyType::<i32>(None);
    assert!(val.0.is_none());
}

struct MyType<T>(Option<T>);

パターン B

トレイトの選択

推論中の型を引数に、適用可能なトレイトを複数の候補から探る事はできない。

なぜなら、これをするとトレイトの候補や組合せが膨大な数になる場合がある。

そして、これは以下のサンプルであげるような少し意外な結果をもたらす。

サンプル

以下では、extend の呼出により vec_dstvec_src が同じ型だと分かりそうだが、これはエラーになる。なぜなら、VecExtend の実装には、impl<T, A> Extend<T> for Vec<T, A>impl<'a, T, A> Extend<&'a T> for Vec<T, A> の二種類がある。


fn main() {
    let mut vec_dst = Vec::<i32>::new();
    let vec_src = Vec::new();
    vec_dst.extend(vec_src);
}

error[E0282]: type annotations needed for `Vec<_>`
 --> src\main.rs:3:9
  |
3 |     let vec_src = Vec::new();
  |         ^^^^^^^   ---------- type must be known at this point
  |
help: consider giving `vec_src` an explicit type, where the type for type parameter `T` is specified
  |
3 |     let vec_src: Vec<T> = Vec::new();
  |                ++++++++

解決策

基本形と同じ解決策が使える。

他にも、トレイトのメソッド呼出を完全修飾記法に変更してもよい。