error[E0282]: type annotations needed
error[E0282]: type annotations needed for `Xxx`
型推論が失敗した場合について。
型推論とは、型を明示せず周辺コードから推論する機能である。
例えば、以下の二行は同じ意味になる。
let a: bool = true;
let a = true;
これにより、冗長な型の記述がなくなる。代わりに、周辺コードが複雑だと型が一目では判別できなくなる。しかし、傾向としては長所が短所を上回る。また、最近は IDE が省略された型をすぐに調べてくれる。
推論時にコードのどの範囲まで調べるかは言語により差がある。
2026 年現在の多くの言語 (C#, Java, TypeScript など) では文を追わない。そのため、変数型の型推論では右辺のみから型が決まる。この方法は非常に分かりやすいが、推論できる箇所が少ない。
一方、Rust では文を追いながら型情報が補完されていく。例えば以下では、変数 vec の型は宣言から Vec<_> と推論され、push の呼出から Vec<i32> と推論される。
fn main() {
let mut vec = Vec::new();
vec.push(42);
assert_eq!(vec.pop(), Some(42));
}
型推論のための情報が不足しているパターン。
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); | +++++++++++
エラーメッセージにもあるが、変数宣言で型を明示すればよい。
fn main() {
let val: MyType<i32> = MyType(None);
assert!(val.0.is_none());
}
struct MyType<T>(Option<T>);
値の生成時に型を明示する方法もある。
fn main() {
let val = MyType::<i32>(None);
assert!(val.0.is_none());
}
struct MyType<T>(Option<T>);
推論中の型を引数に、適用可能なトレイトを複数の候補から探る事はできない。
なぜなら、これをするとトレイトの候補や組合せが膨大な数になる場合がある。
そして、これは以下のサンプルであげるような少し意外な結果をもたらす。
以下では、42 との比較で x が i32 型だと分かりそうだが、これはエラーになる。なぜなら、== 演算子のためには Eq トレイトが必要になる。しかし、Eq トレイトには i32 のための実装だけでなく、他の型のための実装も存在する。
fn main() {
let x = "42".parse().unwrap();
assert!(x == 42);
}
error[E0284]: type annotations needed --> src\main.rs:2:9 | 2 | let x = "42".parse().unwrap(); | ^ ----- type must be known at this point | = note: cannot satisfy `<_ as FromStr>::Err == _` help: consider giving `x` an explicit type | 2 | let x: /* Type */ = "42".parse().unwrap(); | ++++++++++++
以下では、extend の呼出により vec_dst と vec_src が同じ型だと分かりそうだが、これはエラーになる。なぜなら、Vec の Extend の実装には、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(); | ++++++++
基本形と同じ解決策がどちらのサンプルにも使える。
他にも、トレイトのメソッド呼出を完全修飾記法に変更してもよい。