error[E0277]: the trait bound `Type: Trait` is not satisfied
期待されるトレイト境界に型が適合しなかった。
単純にトレイト境界を満たさないパターン。
以下では、関数 func
の引数 arg
は MyTrait
境界に適合しなければならない。
しかし、実引数として指定された値 false
は bool
型でそれに適合していない。
fn main() {
func(false);
}
fn func<T: MyTrait>(arg: T) {
println!("arg: {}", arg.text());
}
trait MyTrait {
fn text(&self) -> &str;
}
error[E0277]: the trait bound `bool: MyTrait` is not satisfied --> src\main.rs:2:10 | 2 | func(false); | ---- ^^^^^ the trait `MyTrait` is not implemented for `bool` | | | required by a bound introduced by this call | help: this trait has no implementations, consider adding one --> src\main.rs:9:1 | 9 | trait MyTrait { | ^^^^^^^^^^^^^ note: required by a bound in `func` --> src\main.rs:5:12 | 5 | fn func<T: MyTrait>(arg: T) { | ^^^^^^^ required by this bound in `func`
トレイト境界を満たすよう型にトレイト実装を追加する。
fn main() {
func(false);
}
fn func<T: MyTrait>(arg: T) {
println!("arg: {}", arg.text());
}
trait MyTrait {
fn text(&self) -> &str;
}
impl MyTrait for bool {
fn text(&self) -> &str {
if *self { "T" } else { "F" }
}
}
derive
属性
問題のトレイト境界が derive
属性によるパターン。
『derive 属性 - 型パラメタの影響』で紹介する通り、derive
属性は型パラメタについての境界を導入する場合が多い。この境界に違反するとエラーになる。なお、下記のサンプルではエラーメッセージがその境界 T: Default
について指摘しているが、ソース中に該当箇所が存在しない。そのため、混乱しやすい。
以下では、MyVec<T>
の Deault
の実装は derive
属性に由来するため、T: Default
の境界を持つ。しかし、MyVec::default()
の呼出箇所の T
は Clone
しか実装していない。
fn main() {
let values = values(1, 3);
assert_eq!(values.0, vec![1, 1, 1]);
}
fn values<T: Clone>(value: T, len: usize) -> MyVec<T> {
let mut ret = MyVec::default();
for _ in 0..len {
ret.0.push(value.clone());
}
ret
}
#[derive(Default, Clone, PartialEq)]
struct MyVec<T>(Vec<T>);
error[E0277]: the trait bound `T: Default` is not satisfied --> src\main.rs:7:19 | 7 | let mut ret = MyVec::default(); | ^^^^^ the trait `Default` is not implemented for `T` | note: required for `MyVec<T>` to implement `Default` --> src\main.rs:15:10 | 15 | #[derive(Default, Clone, PartialEq)] | ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro help: consider further restricting type parameter `T` with trait `Default` | 6 | fn values<T: Clone + std::default::Default>(value: T, len: usize) -> MyVec<T> { | +++++++++++++++++++++++
derive
属性による境界が問題の場合、それを除去したコードを手動で記述する。
fn main() {
let values = values(1, 3);
assert_eq!(values.0, vec![1, 1, 1]);
}
fn values<T: Clone>(value: T, len: usize) -> MyVec<T> {
let mut ret = MyVec::default();
for _ in 0..len {
ret.0.push(value.clone());
}
ret
}
#[derive(Clone, PartialEq)]
struct MyVec<T>(Vec<T>);
impl<T> Default for MyVec<T> {
fn default() -> Self {
Self(Default::default())
}
}