error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
メッセージには型パラメタ版、定数パラメタ版、そしてライフタイムパラメタ版がある。
どれも似た内容のため、ここでは主に型パラメタ版について説明する。
impl
ブロックの各ジェネリクスパラメタは、impl
の対象となる型から、それぞれの具体的な内容が決まるよう、それぞれが適切に制約されていなければならない。
以下はエラーになる (後述のパターン C)。
impl<T, U> MyType<T> where T: MyTrait<U>
これが許されると、型がこの実装に適合しても、型パラメタ U
の具体的な内容が決まらないパターンがでてきてしまう。例えば、この実装に適合する型 MyType
において、SomeType
は MyTrait
に適合する。しかしここで、SomeType
は MyTrait
と MyTrait
に同時に適合するかもしれない。
殆どの場合、型やトレイトにダミーのジェネリクスパラメタを追加して、それらに問題のジェネリクスパラメタを指定するとよい。これはつまり、問題のジェネリクスパラメタの内容を明示的に指定できるようにしている。詳細は各パターンの解決策を参照。
以下は E0207 についての公式からの引用。
impl
の任意の型や定数パラメタは以下の基準の少なくともどれか一つを満たさなければならない:
- impl が実装する型 の中に表れる。
例.impl<T> Foo<T>
- トレイト実装において、実装されるトレイト の中に表れる。
例.impl<T> SomeTrait<T> for Foo
- 関連型としてバインドされている。
例.impl<T, U> SomeTrait for T where T: AnotherTrait<AssocType=U>
ライフタイムパラメタが関連型として使われている場合、
impl
での制限なしのライフタイムパラメタはサポートされない。
以下では、型パラメタ T
がどこにも使われていない。
pub struct MyType();
impl<T> MyType {}
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates --> src\lib.rs:2:6 | 2 | impl<T> MyType {} | ^ unconstrained type parameter
ダミーの型パラメタを持たせるとよい。
use std::marker::PhantomData;
pub struct MyType<T>(PhantomData<T>);
impl<T> MyType<T> {}
以下では、関連関数で型パラメタを使っているが、やはりエラーになる。
pub struct MyType();
impl<T> MyType {
pub fn f(_: T) {}
}
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates --> src\lib.rs:2:6 | 2 | impl<T> MyType { | ^ unconstrained type parameter
型パラメタの宣言を関連関数の側で行えばよい。
pub struct MyType();
impl MyType {
pub fn f<T>(_: T) {}
}
where
でのみ型パラメタを使用
以下では、where
で型パラメタを使っているが、やはりエラーになる。
pub struct MyType<T>(T);
pub trait MyTrait<T> {}
impl<T, U> MyType<T> where T: MyTrait<U> {}
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> src\lib.rs:3:10 | 3 | impl<T, U> MyType<T> where T: MyTrait<U> {} | ^ unconstrained type parameter
ダミーの型パラメタを持たせるとよい。
use std::marker::PhantomData;
pub struct MyType<T, U>(T, PhantomData<U>);
pub trait MyTrait<T> {}
impl<T, U> MyType<T, U> where T: MyTrait<U> {}