Rustでのエラー『type parameter `_` must be used as the type parameter for some local type』について。
現在ironフレームワークを用いたWebプログラミングを勉強しています。
その中でセッション周りの実装の際に、ironが提供するトレイトを実装している型をキーにしていろいろやり取りをするのですが、以下のようにわかりやすく実装しなおそうと思っています。(説明が長くなりますすみません...)
セッションを扱うには、自身で定義した2つのstruct(Session
, SessionKey
とします)に対し、ironクレートによって提供されているtypemap::Key
トレイトを次のように適用します。
struct Session; // セッションデータとして扱う構造体(自分はHashMapを1つ持つタプル構造体にしています)
struct SessionKey; // 関数を呼ぶ際、扱う型を決定するのに使用します
// 例)get_ref::<SessionKey>() -> &Sessionが返される
impl typemap::Key for SessionKey {
type Value = Session;
}
このようにimplすることで、上の例のようにSessionKey
をキーにしてSession
構造体をやり取りします。
わかりやすさのために、typemap::Key, Value
ではなく次のような名前で扱おうと考えています。
trait SessionType {
type SessionData;
}
という名前で定義したトレイトと関連型を、
impl SessionType for SessionKey {
type SessionData = Session;
}
同じようにimplします。
これによって、typemap::Key
のimplは内部に隠しつつ、わかりやすい名前で扱えないかと考えています。
なので次のように実装しました。
extern crate iron;
use iron::typemap;
struct Session;
struct SessionKey;
// こっちを使いたい
trait SessionType {
type SessionData;
}
// このように実装したい(見える部分)
impl SessionType for SessionKey {
type SessionData = Session;
}
// こちらを追加(見えない部分)
impl<S: SessionType> typemap::Key for S {
type Value = <S as SessionType>::SessionData;
}
fn main(){
// ...
}
impl<S: SessionType> typemap::Key for S {
type Value = <S as SessionType>::SessionData;
}
これは、SessionType
トレイトを実装している全ての構造体に対し、typemap::Key
を実装します。またその構造体にSessionType
トレイトを実装した際のtype Session
に指定した型<S as SessionType>::SessionData
をValue
に指定します。こうすることでtypemap::Key
の実装を見える部分で行う必要がなくなると考えました。
しかしエラーになります。
error[E0210]: type parameter `S` must be used as the type parameter for some local type (e.g. `MyStruct<T>`);
only traits defined in the current crate can be implemented for a type parameter
--> src\main.rs:17:1
|
17 | / impl<S: SessionType> Key for S {
18 | | type Value = <S as SessionType>::Session;
19 | | }
| |_^
このエラーの原因がわかりません。
ちなみに
trait Key {
type = Value;
}
というトレイトを自分で定義し、typemap::Key
と同じように書いた場合はエラーが出ませんでした。(しかしironの関数を利用するにはtypemap::Key
の実装が必要...)
これはtypemap::Key
が外部で定義されているから無理ということなのでしょうか?しかしエラー文からはそのように読み取れないので理由がわかりません。
長文になってしまい申し訳ありません。
このエラーの原因と回避の仕方がわかる方いらっしゃいませんか?