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())
}
}