
2025/12/23 4:25
「Rustにおけるローンの代数」
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Rust の借用チェッカーは、メモリ所有権・初期化・移動制限をより細かく制御できる豊富な参照型をサポートするようになりました。従来の共有 (
&) と可変 (&mut) 借用に加えて、論文では新しい種類―&own、&uninit そして &pin T、&pin mut T、&pin own T のようなピンニングバリアント―を導入しています。
Place
「place」とは、識別子やフィールドのデリファレンスで表される任意のメモリ位置(例:
x、*x、x.field)です。各ローンは、借用した place、その参照種別、およびライフタイムを記録します。記事では、すべての参照型について、ライブ時・期限切れ後・既にドロップされた場合に許可される操作(読み取り、書き込み、移動、ドロップ、再借用)を詳細に示した表が掲載されています。
主な意味論
(別名&own T
)は完全所有権を付与します。ローンが終了すると値は自動的にドロップされ、移動することも可能です。&move T
は割り当てられたが未初期化の場所を指し、初期化が完了するまで書き込みのみ許可されます。初期化後は任意の参照型として再借用できます。&uninit T- ピンニング参照は「ピンニング要件」を追加し、
を実行せずにポインタ先の値を移動または解放できないようにします。期限切れでもピンは有効であり、非ピン可変借用がブロックされます。Drop
は&pin mut T
に相当し、async future では不可欠です。Pin<&mut T>
(&pin T
)とPin<&T>
は提案されていますがあまり一般的ではありません。&pin own T
は&own T
として再借用できますが、&pin own T
を&pin own T
に渡すことはできません。mem::forget- ピンニングは値の性質であるため、
のような構成は未定義です。&pin uninit T
論文では、これら新しい参照型を安定化させ、再借用規則(例:
&own → &pin own T を許可)を洗練し、ピンニングが参照特性ではなく値のプロパティとして振る舞うことを明確にすることを提案しています。安全な API(例えば Vec::pop_own や初期化ヘルパー MyType::init(&uninit self) -> &own Self)を公開することで、開発者はメモリ安全性をより厳密に制御できるようになり、特に async および低レベルのコンテキストで、早期移動や未初期化データに起因するバグを減らすことが期待されます。
Text to translate
(incorporating missing details):**
Rust’s borrow checker now supports a richer set of reference types that give programmers finer control over memory ownership, initialization, and movement restrictions. In addition to the familiar shared (
&) and mutable (&mut) borrows, the paper introduces new kinds—&own, &uninit, and several pinning variants such as &pin T, &pin mut T, and &pin own T.
A place is any memory location expressed as an identifier or field dereference (e.g.,
x, *x, x.field). Each loan records the place it borrows, its reference kind, and its lifetime. The article presents tables that detail which operations are allowed for every reference type while live, after expiration, or when already dropped—covering reads, writes, moves, drops, and reborrowing.
Key semantics:
(also called&own T
) grants full ownership; the value is dropped automatically when the loan ends, and it can be moved out.&move T
refers to an allocated but uninitialized location; only writes are permitted until the place becomes initialized, after which it may be reborrowed as any other reference type.&uninit T- Pinning references add a “pinning requirement” that forbids moving or deallocating the pointed‑to value without running
, even after the pin expires. Thus an expired pin still blocks non‑pin mutable borrows until the value is dropped.Drop
corresponds to&pin mut T
and is essential for async futures;Pin<&mut T>
(&pin T
) andPin<&T>
are proposed but less common.&pin own T- A
can be reborrowed as&own T
, but&pin own T
cannot be passed to&pin own T
.mem::forget - Pinning is a property of the value, so constructs like
are undefined.&pin uninit T
The paper proposes stabilizing these new reference types, refining reborrowing rules (e.g., allowing
&own → &pin own T), and clarifying that pinning behaves as a value property rather than a reference trait. By exposing safer APIs—such as Vec::pop_own or initialization helpers (MyType::init(&uninit self) -> &own Self)—developers gain tighter control over memory safety, especially in async and low‑level contexts, potentially reducing bugs involving premature moves or uninitialized data.本文
Rust の借用チェックの核心
借用を取ると、借用が終了するまでその場所へのアクセスは制限されます。
たとえば、可変借用中にその場所から読み取りはできません。
近頃、人々は「共有」/「可変」だけでなく、より多くの情報を借用チェッカーへ教える方法について議論しています。以下は、新しい参照型がどのように相互作用するかを示す表と、それぞれの型の説明です。
用語集
| 用語 | 意味 |
|---|---|
| place | メモリ上の場所、例:, , など |
| taking a borrow | , , 等を評価すること |
| loan | 借用が取られた事実。借用した場所と参照の種類を覚えており、結果として返される参照に新しいライフタイムが付与されます。ローンは、そのライフタイムが何らかの値の型に現れている限り 生きている とみなされます |
| While a loan is live | 借用された場所へのさらなる操作が制限されます |
| After a loan expires | 制約は変わる可能性があります(下表参照) |
注
表はすべてのニュアンスを網羅しているわけではありません。
に書き込むと&uninitと再借用でき、逆も同様です。&own- ある場所の内容をドロップすると、その場所に対するピン留め制約は消失します。
表 1 – 与えられた参照で可能な操作
| 参照 → | | | | | | | |
|---|---|---|---|---|---|---|---|
| Read | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Write | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
| Move out | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Drop | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ |
例:
からは&own Tと再借用できますが、&mut Tはできません。&pin own T
表 2 – ローンが生きている間に場所で行えること
| Loan type → | | | | | | | |
|---|---|---|---|---|---|---|---|
| Read | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Write | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
ほとんどの場合借用は排他であるため、何も行えません。
表 3 – ローンが終了した後に可能な操作
| Loan type → | | | | | | | |
|---|---|---|---|---|---|---|---|
| Read | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ |
| Write | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Move out | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Drop | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ |
と&ownは終了後に同じ振る舞いをします。場所は未初期化とみなされ、書き込みと&uninitの借用のみが許可されます。&uninit
これらの新しい参照型はなぜ必要か?
これは広く議論された仮説的アイデアです。Rust の安全性保証を破ることなく、借用チェックに表現力を追加します。
所有参照 &own T
&own T-
(別名&own T2
)は完全な所有権を付与する参照です。&move T
値がスコープから外れたときにドロップされますが、実際の割り当ては型によって制御されません。 -
から値を移動出すことは許可されています。値をドロップすると借用が終了し、その場所は未初期化となります。&own
impl Vec<T> { fn pop_own(&mut self) -> Option<&own T> { /* ... */ } fn drain_own(&mut self) -> impl Iterator<Item = &own T> { /* ... */ } }
未初期化参照 &uninit T
&uninit T
(別名&uninit T
)は割り当てられたがまだ初期化されていない場所を指します。&out T
書き込みのみ許可され、書き込んだ後は他の参照として再借用できます。
impl MyType { fn init(&uninit self) -> &own Self { *self = new_value(); &own *self } } let x: MyType; let ptr: &own MyType = MyType::init(&uninit x);
と&uninit
は、期限切れ後に元の場所を未初期化とみなすという性質を共有します。&own
ピン留め参照 &pin T
, &pin mut T
, &pin own T
&pin T&pin mut T&pin own Tピン留めは値を移動させたり、
Drop を実行せずにデアロケートしたりすることを禁止します。ピン留め借用が終了しても制約は残ります。
→&pin mut T
(非同期コードで頻繁に使用)。Pin<&mut T>
→&pin T
.Pin<&T>
は所有バリアントで、&pin own T
に渡すことはできません。mem::forget
再借用ルール:
を&own T
として再借用できます。ピン保証は保持されます。&pin own T
結論
これらの新しい参照型は、所有権・初期化・ピン留めに対するより細かな制御を提供しつつ、Rust の安全性保証を維持します。まだ仮説的ですが、コミュニティ内で長い間議論され洗練されています。