RustコアチームがRust 1.21をリリースした。リテラルの柔軟性を高める新たな言語機能に加えて、ライブラリの安定性向上とツールサポートの改善が行なわれている。

Rustの新しい言語機能では、スタックではなく静的メモリに格納された変数にリテラルを昇格することが可能になり、リテラルの参照を安全に渡せるようになる。この変更に伴って、次のようなコードが有効になる。

let x: &'static u32 = &5; thread::spawn(move || { println!("{}", x); });

以前のバージョンのRustでは、このようなコードは、スレッド本体の x で参照されるリテラル 5 の生存期間に問題があるものとして、コンパイラによって拒否される。ここで問題なのは、 5 がスタックに配置されているため、関数の終了時に削除される点である。リテラルの生存時間をスタックまき戻し以降にまで拡張するため、Rust 1.21のコンパイラは、上記のコードを大まかに言って次のようなコードに変換する。

static FIVE: i32 = 5; let x = &FIVE;

ツーリングの面では、翻訳フェーズの実行中にLLVMが動作することにより、コンパイラのメモリ使用量が削減されている。これによるメリットは２つある。まず、２つのフェーズを効果的に並列化し、メインスレッドで翻訳とLLVM実行を切り換えることが可能になる。さらにrustpでは、“ rustp component add rls-preview ”を実行するRust言語サーバ(RLS)のインストールがサポートされるようになる。Rustコア開発者によると、これはRLSやClippy、rustfmtなどのRustツールをナイトリビルドではなく、Rustの安定ビルドで実行可能にするための第一歩である。

ライブラリの安定化に話題を移すと、次のようなコードの for ループを Iterator::for_each に置き換えられるようになった。

// old for i in 0..10 { println!("{}", i); } // new (0..10).for_each(|i| println!("{}", i));

This change makes it easier to chain a number of iterators together, like in the following example:

(0..100) .map(|x| x + 1) .filter(|x| x % 2 == 0) .for_each(|i| println!("{}", i));

さらに、 max と min 関数が Ord トレート上に移動して、トータルオーダセットを形成するタイプで使用されるようになった。単一およびスレッド化された参照カウンタである Rc<T> と Arc<T> には、 From<&[T]> where T: Clone 、 From<str> 、 From<String> 、 From<Box<T>> where T: ?Sized 、 From<Vec<T>> といった、より親しみやすいインターフェースが用意された。

Rustの最新バージョンは、 rustup update stable を実行すれば入手できる。新機能の詳細に関しては、1.21リリースノートを見落とさないようしてほしい。