Rustプロジェクトの目標: 不動タイプと保証されたデストラクタ
概要
Rustプロジェクトの目標では、メモリ内での移動や mem::forget による忘却をオプトアウトできる Move および Forget オートトレイトの導入が提案されています。これにより、不動タイプ(immobile types)と保証されたデストラクタが可能になります。
動機
現在のRustは、すべてのタイプが移動可能かつ忘却可能であることを前提としています。これは自己参照型(self-referential types)を妨げ、デストラクタの実行を保証できない原因となっています。不動タイプにはその生存期間全体を通じて安定したアドレスが必要であり、保証されたデストラクタは、リソースをクリーンアップせずに残してしまう mem::forget によるリークを防ぎます。
提案
新しい unsafe オートトレイトである Move, Destruct, そして Forget は、機能をタイプとして定義します。!Move は不動性を、!Forget は保証されたデストラクタを意味します。
Move トレイト
Move トレイトは、メモリ内での移動が可能なタイプをマークします。!Move タイプは移動できず、その存在期間全体を通じて安定したアドレスを保持しなければなりません。これにより、不動性は「場所(place)」のプロパティではなく、Pin のような場所のプロパティではなく、タイプとしてのプロパティになります。
Forget トレイト
Forget トレイトは、mem::forget を介してデストラクタを実行せずに忘却できるタイプをマークします。!Forget タイプは忘却できず、デストラクタの実行が保証されます。これにより、ハンドルがタスクのデストラクタで join するような、安全なスコープ付きスパン(safe scoped spawn)といったパターンが可能になります。
作業項目
次の一年で、チームは以下を行います:
Moveトレイトのコンパイラサポートの実装 (@lcnr および @nia-e)。MoveRFC の作成 (@yoshuawuyts)。- Linux カーネルにおける
Moveのテスト (@BennoLossin)。 Iteratorと!Moveの相互作用のテスト (@yoshuawsh? 実際には @yoshuawuyts)。- 保証されたデストラクタのための設計オプションの探索 (@nikomatsakis)。
他の作業との関係
この取り組みは、すべてのタイプがコンパイル時にサイズが既知であるという仮定を緩和する Sized ヒエラルキーの作業と同じパターンに従います。ここでは、「すべてのタイプは移動可能である」および「すべてのタイプは忘却可能である」という仮定を緩和します。
これは Pin のエルゴノミクス(使いやすさ)の取り組みに対する代替案として提示されており、最終的には不動性を場所のプロパティではなくタイプとしてのプロパティにすることで、Pin を非推奨にする(deprecate)ことを目指しています。
よくある質問
- この作業は Sized ヒエラルキーの作業とどのように関係していますか? 両方とも、タイプが以前の普遍的な仮定をオプトアウトできるトレイト・ヒエラルキーを導入します。
Sizedはコンパイル時に既知のサイズを緩和し、MoveとForgetは移動可能性と忘却可能性を緩和します。 - この作業は Pin のエルゴノミクスに関する取り組みとどのように関係していますか?
Pinのエルゴノミクスに関する取り組みは、言語レベルのpin場所(pin places)と特別なDropオーバーロードを追加します。一方、このプロジェクトは不動性をタイプとしてのプロパプトとして扱い、Pinやその重複定義の問題を回避します。 - 何が安全なスコープ付きスパンを可能にしますか?
!Forgetを実装するタイプのハンドルはmem::forgetされることができず、デストラクタの実行が保証されます。そのため、ハンドルはスパンされたタスクをjoinすることができ、タスクがスコープを超えて生存することを防ぎます。 - この設計空間についてもっと詳しく読むにはどうすればよいですか? 目標(goal)は、
Move、Destruct、Leak、must-moveタイプ、エルゴノミックな自己参照型、Pinの問題、および!Move構築のためのplacing functionsに関するいくつかのブログ記事へのリンクが含まれています。
コミュニティの反応
コメント投稿者は、言語の長年の欠落を埋めることに対して熱意を示しています: