BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース 機能の安定化とNLLのバックポートを備えたRust 1.36

機能の安定化とNLLのバックポートを備えたRust 1.36

原文(投稿日:2019/07/18)へのリンク

Rust 2018のロードマップに続くRust 1.36で最も待ち望まれていた新機能は、同言語でasync/awaitを実現するための最初のステップとなる、Futureトレイトのサポートだ。さらに、ボローチェッカの向上を目的としてNLL(non-lexical lifetime)がバックポートされた他、stdを必要としないメモリ割り当て依存ライブラリの構築を可能にするために、新たなallocクレートが導入されている。

Rustでは、フューチャはFutureトレイトを通じてサポートされており、そのコアメソッドであるpollがフューチャの解決に使用される。最終値がまだ準備できていない場合、pollは現在のタスクを一時停止し、その後pollが可能になった時点で再起動する。ポーリングタスクでは、Futureの再起動に使用するWakerを指定することができる。解決した後は、Futureはポーリングされない。このためパニックが発生したり、呼び出しタスクを無期限にブロックするなどの問題が発生する可能性がある。重要なのは、しかしながら、pollsafeメソッドであって、どのような条件下でもメモリ破壊しない実装であるという保証をすることだ。

Rust 1.31(Rust 2018)で導入されたNLLが、Rust 2015でも使用できるようになった。Rust 2015でNLLがサポートされたため、古いボローチェッカは間もなく言語から削除されることになる。この移行を安全に行なうために、新たなボローチェッカでは、古いボローチェッカでは受け入れられていたが、新たなボローチェッカでは違反になるコードに対して、警告を発するようになる予定だ。NLLによって、レキシカルスコープにバインドする必要なく、変数の実際の有効期間が考慮されるようになる。これはRustのボローチェッカにとって大きな改善だ。

もうひとつの新たな安定機能はallocクレートである。これは、グローバルメモリアロケータを分析し、それに依存するすべてのタイプをstdから取り出す作業を行った成果だ。結果としてstdは、これらのタイプをすべてallocからインポートし、互換性維持のために再びエクスポートするようになる。メモリ割り当てを必要とするライブラリクレートは、同じようにalloc直接インポートできるので、stdに依存関係を持つ必要がなくなる。stdは非常に大規模なクレートであるため、組み込みシステムなど、すべての環境で必ずしも使用できるとは限らないのだ。Rustチームによると、これは、より大きな#![no_std]ライブラリエコシステムを構築可能にする上での重要なステップになる。allocのサポートは、ライブラリクレートに対してのみ安定化されていることに注意が必要である。つまり#![no_std]バイナリでallocを使用可能にするためには、引き続き夜間ビルド(非安定版)のRustが必要となる。結果として、次のように記述することで、グローバルメモリアロケータに依存する#![no_std]ライブラリを作成することができる。

#![no_std]

extern crate alloc;

Rust 1.36にはさらに、mem::uninitializedを廃止するための道筋も用意されている。このメソッドは言語に残すには危険過ぎるものと考えられており、より安全なMaybeUninit<T>の使用に置き換えられる予定である。mem::uninitializedは従来、Rustの初期化チェックをバイパスして遅延割り当てを実装する目的で使用されていた。ただひとつ問題なのは、この機能を使用することで、その値が正しく初期化されるものとコンパイラが想定するため、Rustの持つ安全性が台無しになることだ。新たに用意されたMaybeUninit<T>型は、サポートする動作はほぼ同じだが、プログラマに対して、可能であれば正常な初期化の後で、.assume_init()を使ってその値を使用する意図を明示的に表現するように要求する点が異なる。

最後に注目すべき点として、Rust 1.36ではHashMap<K,V>の実装が新しくなり、SwissTableを使用することによって、平均速度の向上と、メモリオーバヘッドの低減が実現されている。

この記事に星をつける

おすすめ度
スタイル

特集コンテンツ一覧

BT