Foo
を定義しているタイミングに注目してほしいのだけど、以下の実装がエラーや警告もなく普通に動く1
fn main() { let a: Foo = 10; println!("{}", a); type Foo = u32; // Fooの利用箇所より下の行で定義している }
(変数の定義なんかと同じで)使うタイミングより前で定義しておかないとだめだと思いこんでいたけど、どうやらそんなことはないらしい。ちょっとびっくりした 2
話は以上なんだけど、気になった点をいくつか試したので以下にメモを残しておく
型エイリアスの定義を消してみる
上の場合だと type
文がいらないという可能性がなくはないので念の為確認してみる
fn main() { let a: Foo = 10; println!("{}", a); }
$ rustc main.rs error[E0412]: cannot find type `Foo` in this scope --> main.rs:2:12 | 2 | let a: Foo = 10; | ^^^ not found in this scope error: aborting due to previous error For more information about this error, try `rustc --explain E0412`.
普通にエラーになった。やっぱり単に先に定義が反映されているだけっぽい
型エイリアス間の順序関係を確認してみる
どうやら type
は先に反映されるっぽいことはわかったが、それなら type
間の順序関係はどうなるのか気になった
fn main() { let a: Bar = 10; type Foo = u32; type Bar = Foo; println!("{}", a); }
fn main() { let a: Bar = 10; type Bar = Foo; type Foo = u32; println!("{}", a); }
この2つの実装はどちらも正常に機能する。 Foo
を先に定義してないと type Bar = Foo
がエラーになるのではと思っていたが(つまり type
間には順序関係があるのではと思っていたが)、そういうわけではなさそう
型エイリアス間の順序関係を確認してみる_2
順不同で反映されるなら、同じ名前のエイリアスを複数指定したらどうなるのか気になった
fn main() { let a: Foo = 10; type Foo = u32; type Foo = f32; println!("{}", a); }
$ rustc main.rs error[E0428]: the name `Foo` is defined multiple times --> main.rs:4:5 | 3 | type Foo = u32; | --------------- previous definition of the type `Foo` here 4 | type Foo = f32; | ^^^^^^^^^^^^^^^ `Foo` redefined here | = note: `Foo` must be defined only once in the type namespace of this block error: aborting due to previous error For more information about this error, try `rustc --explain E0428`.
これはエラーになる
型エイリアスのスコープを確認してみる
もしかしてブロックよりも大きな単位でエイリアス反映されちゃったりするのかなと不安になったので確認しておく
fn main() { let a: Foo = 10; { type Foo = f32; } println!("{}", a); }
$ rustc main.rs error[E0412]: cannot find type `Foo` in this scope --> main.rs:2:12 | 2 | let a: Foo = 10; | ^^^ not found in this scope error: aborting due to previous error For more information about this error, try `rustc --explain E0412`.
これはエラーになる。ブロックのstatementを上から順番にみていくちょうど前のタイミングで、ブロックの中の type
を一通り見ているっぽい
補足
-
バージョンは
rustc 1.42.0 (b8cedc004 2020-03-09)
です↩ -
rust-analyzer の実装をみてる限りどうにも
type
の順序を考慮している気がしなくて、実際に試してみたら……という感じでした。見ていたのはこのあたり rust-analyzer/expr.rs at e0de2475208765a171f335dfffde764f96243d41 · rust-analyzer/rust-analyzer · GitHub↩