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> において、SomeTypeMyTrait<U> に適合する。しかしここで、SomeTypeMyTrait<i32>MyTrait<u32> に同時に適合するかもしれない。

解決策

殆どの場合、型やトレイトにダミーのジェネリクスパラメタを追加して、それらに問題のジェネリクスパラメタを指定するとよい。これはつまり、問題のジェネリクスパラメタの内容を明示的に指定できるようにしている。詳細は各パターンの解決策を参照。

仕様

以下は 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 での制限なしのライフタイムパラメタはサポートされない。


パターン

パターン A

基本形

以下では、型パラメタ 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> {}

パターン B

関連関数でのみ型パラメタを使用

以下では、関連関数で型パラメタを使っているが、やはりエラーになる。


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

パターン C

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> {}