Rustの基本型の名前解決
Rustの基本型の名前はキーワードではない。したがって基本型の名前は名前解決と同時に処理されることになる。ところがややこしい点として、基本型と同名のモジュールに解決される場合もある。この挙動について調べた。
基本型の名前は PrimitiveTypeTable::new
で列挙されており、以下の名前を含んでいる。
bool
char
i8
,i16
,i32
,i64
,i128
,isize
u8
,u16
,u32
,u64
,u128
,usize
f32
,f64
str
なお、これらに含まれない(記号で表される)基本型としては、&'a T
, &mut 'a T
, *const T
, *mut T
, [T; n]
, [T]
がある。処理系が特別扱いする Box<T>
, PhantomData<T>
, NonZero<T>
, UnsafeCell<T>
なども基本型に準じると考える場合があるかもしれない。
基本型の名前の処理は resolve_qpath
の中 で行われている。QPathは式や型などに出てくるものであり、例えば use
のパスはこの処理の対象外であり、常に通常の名前として解決されるということになる。
このコードによると、パスの最初の要素が基本型として処理される条件は
- パスはQSelf (
<A as Foo>::
のような部分) を含まない。 - パスの最初の要素が、上記の基本型の名前のいずれかである。
- パスの最初の要素が、型名前空間で解決されようとしている。
- 通常の方法でのパスの解決に失敗したか、またはパス全体が正規モジュール(ルートモジュールまたは
mod
)に解決された。
である。
これにより、例えば
use std::f64; fn main() { let x : f64 = 0.0f64; println!("{}", f64::sin(f64::consts::PI + x)); }
というコードがうまく動作することになる。ここで、 x
の型と、 f64::sin
の f64
は、基本型に解決される。一方、 f64::consts::PI
の f64
は、 ::std::f64
モジュールとして解決される。
ソースコードには、この挙動は「後方互換性のため」と書いてあるが、これが将来のサポート廃止を意図しているのか、そうではないのかは、判断がつかない。(少なくともサポート廃止という話を聞いたことはない)
なお、以下の2つは別の場所で解決される。