Pixel Pedals of Tomakomai

北海道苫小牧市出身の初老の日常

PinはUnpin

未だにきちんと型が読めなくて困る。

Pinning - Asynchronous Programming in Rust

To use a Future or Stream that isn't Unpin with a function that requires Unpin types, you'll first have to pin the value

!Unpin でも Box::pinUnpin になると書いてあるのだが、ドキュメントを見るとなんか違う気がする。

Pin in std::pin - Rust

impl<Ptr> Unpin for Pin<Ptr>
where
    Ptr: Unpin,

where によれば Ptr は「 Unpin である必要」があり、 !Unpin では駄目な気がする。答えを言えば、ポインタである Box&mut はどう考えても Unpin なわけで、 Pin<Box<...>> の形であれば Unpin なのである。同じく「 Unpin である必要」がある DerefMut と定義を比べるとわかる。

impl<Ptr> DerefMut for Pin<Ptr>
where
    Ptr: DerefMut,
    <Ptr as Deref>::Target: Unpin,

こちらは DerefTargetUnpin である必要があり、 !UnpinBox で包んでも駄目なのである。 Deref の定義も念のためあわせて記載するとこうなる。

pub trait Deref {
    type Target: ?Sized;

    // Required method
    fn deref(&self) -> &Self::Target;
}

型定義もまともに見ずに日本語で雑に一辺倒に「 Unpin である必要」と読んでしまうのは、勘違いの元である。

前に同じ内容を書いたときには、わかっていたんだろうなあ。

hiratara.hatenadiary.jp