Poisoning

全てのunsafeな型は最低限の例外安全性を満たしていることが必要ですが、全ての unsafeな型が最大限の例外安全性を満たしている必要はありません。 仮に型自体が満たしていたとしても、実装が別の意味を暗黙に付与してしまう場合も あります。例えば整数型は間違いなく例外安全ですが、その(訳注: 最大限の例外安全性 を担保する)セマンティクスを独自に持つわけではないため、整数をアップデートする 際にpanicを起こすと、プログラムが一貫性のない状態に陥る可能性があります。

これは通常は問題になることはありません。というのも例外を発見した処理は直後に 死ぬためです。例えばVecを別のスレッドに送り、そのスレッドがパニックし、結果として Vecが奇妙な状態に陥ったとしても、dropされて永久に闇の彼方に葬られてしまうためです。 とはいえ型によってはpanicの境界をまたいでくる場合もあります。

こういった型は、panicに直面した際に、意図的に自分自身をpoisonする可能性があり ます。poisoningは自体は特に何か別の事態を引き起こすわけではありません。一般的に 通常の手続きの継続を止めるべきであることを表しています。よく知られた例として 標準ライブラリのMutex型があります。この型は対応するMutexGuards(lockを取得した際に 返るもの)が、panicによってdropされた際に自分自身をpoisonします。以後Mutexをlock しようとするとErrを返すかpanicします。

Mutexのpoisonは、通常の文脈で語られるRustの安全性とは異なる用途のためのものです。 Mutexを扱うスレッドがlock中にパニックを引き起こした場合、Mutexの中のデータは変更中 であった可能性が高く、一貫性を欠いていたり変更が未完了の状態であったりするため、 そのようなデータを盲目的に扱う危険性に対する安全装置として動作します。 注意しておきたいのはそのような型が適切に実装されていた場合、メモリ安全性確実 に満たしているという点です。つまるところ、最低限の例外安全性は満たしていなくては ならないということです。

しかしながら、Mutexが例えばBinaryHeapを持っていたとして、その値が実際にはヒープ として要件を満たさなかったような場合、そのデータ構造を利用するプログラムが作成者の 意図通りの挙動をするということは考えにくいです。通常とは異なる振る舞いをする でしょう。とはいえ、十分に注意すればそのような場合でもその値が何かに使える 可能性はあります。safeではあるのです。ただ、ナンセンスかもしれませんが。