ジェネリックパラメータ定義
この章では、rustc が導入されたジェネリックパラメータをどのように追跡するかについて説明します。たとえば、ある struct Foo<T> が与えられたとき、rustc は Foo が型パラメータ T を定義していること(そして他のジェネリックパラメータは定義していないこと)をどのように追跡するのでしょうか。
ここでは、for<'a> 構文によって導入されるジェネリックパラメータ(たとえば where 句や fn 型の中のもの)をどのように追跡するかは扱いません。これは Binder に関する章 で別途扱われています。
ty::Generics
item によって導入されるジェネリックパラメータは、ty::Generics 構造体によって追跡されます。item によっては、親 item で定義されたジェネリクスの使用を許可することがあります。これは、ty::Generics 構造体が、ジェネリックパラメータの継承元となる親 item を指定するための optional なフィールドを持つことで実現されています。たとえば、次のコードがあるとします。
trait Trait<T> {
fn foo<U>(&self);
}
foo に使用される ty::Generics には [U] が含まれ、親として Some(Trait) を持ちます。Trait は、親が None である [Self, T] を含む ty::Generics を持ちます。
GenericParamDef 構造体は、ty::Generics のリスト内の個々のジェネリックパラメータを表現するために使用されます。GenericParamDef 構造体には、その名前、defid、パラメータの種類(つまり型、const、ライフタイム)など、ジェネリックパラメータに関する情報が含まれています。
GenericParamDef には、そのパラメータの位置(最も外側の親から数えた位置)を表す u32 のインデックスも含まれています。これは、ジェネリックパラメータの使用を表現するために使われる値です(これについては 型の表現に関する章 で詳しく説明します)。
興味深いことに、現在の ty::Generics には、item に定義された すべての ジェネリックパラメータが含まれているわけではありません。関数の場合、そこに含まれるのは early bound パラメータだけです。