error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)

孤児ルールと型パラメタが絡んだエラー。

原因

孤児ルール』はクレート外部の型やトレイトに厳しい。

一方、型パラメタの対象にはクレート外部の型もなりうる。

そのため、型パラメタが孤児ルールのきっかけになる事がある。

パターン

パターン A

基本形

型パラメタに外部のトレイトを実装しようとしているパターン。

サンプル

以下では、外部の型になりうる T に、外部のトレイト Display を実装している。


use std::fmt::{self, Display, Formatter};

impl<T> Display for T {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "")
    }
}

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
 --> src\lib.rs:3:6
  |
3 | impl<T> Display for T {
  |      ^ type parameter `T` must be used as the type parameter for some local type
  |
  = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
  = note: only traits defined in the current crate can be implemented for a type parameter

パターン B

ローカル型引数つき外部トレイト

孤児ルール / 追加ルール』にある通り、外部トレイトでもローカル由来の型引数を含んでいるとローカル扱いできる場合があり、そのパターンでは孤児ルールが問題にならなくなる。ただし、これには条件があり、問題の型引数より前の型引数または実装対象の型が型パラメタであってはならない。これに違反するとやはりエラーとなる。

サンプル 1

以下では、ForeginTrait<MyType> は型引数にローカル型を含むため、孤児ルールが問題にならなそうだが、実装対象の型が型パラメタのため、結局はエラーになる。

/src/lib.rs

use foreign::ForeignTrait;

struct MyType();

impl<T> ForeignTrait<MyType> for T {}
/foregin/src/lib.rs

pub trait ForeignTrait<T> {}

error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`MyType`)
 --> src\lib.rs:5:6
  |
5 | impl<T> ForeignTrait<MyType> for T {}
  |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`MyType`)
  |
  = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
  = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last

サンプル 2

以下では、ForeginTrait<T, MyType> は型引数にローカル型を含むため、孤児ルールが問題にならなそうだが、その型引数よりも前方に型パラメタがあるため、結局はエラーになる。

/src/lib.rs

use foreign::{ForeginType, ForeignTrait};

struct MyType();

impl<T> ForeignTrait<T, MyType> for ForeginType {}
/foregin/src/lib.rs

pub struct ForeginType();
pub trait ForeignTrait<T, U> {}

error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`MyType`)
 --> src\lib.rs:5:6
  |
5 | impl<T> ForeignTrait<T, MyType> for ForeginType {}
  |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`MyType`)
  |
  = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
  = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last