Skip to content

Interaction between Pin soundness and arbitrary self types #157067

Description

@Darksonn
#![feature(arbitrary_self_types)]
use std::marker::PhantomPinned;
use std::ops::Receiver;
use std::pin::Pin;

trait MyTrait {
    fn hello(self: Pin<&mut Foo<Self>>) -> Pin<&mut Foo<u32>>;
}
impl MyTrait for u32 {
    fn hello(self: Pin<&mut Foo<Self>>) -> Pin<&mut Foo<u32>> {
        self
    }
}

struct Foo<T: ?Sized> {
    _pin: PhantomPinned,
    val: T,
}

impl<T: ?Sized> Receiver for Foo<T> {
    type Target = T;
}
impl Unpin for Foo<dyn MyTrait> {}

fn pin_it(r: &mut Foo<u32>) -> Pin<&mut Foo<u32>> {
    Pin::<&mut Foo<dyn MyTrait>>::new(r).hello()
}

In the above piece of code, I'm able to convert a &mut Foo<u32> into a Pin<&mut Foo<u32>> even though the type Foo<u32> is !Unpin.

I'm not sure if you can concretely abuse this to trigger UB right now, but it seems bad.

Related test case:

use std::marker::PhantomPinned;
use std::pin::Pin;
trait MyUnpinTrait {
fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned>;
}
impl MyUnpinTrait for PhantomPinned {
fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned> {
self
}
}
impl Unpin for dyn MyUnpinTrait {} //~ ERROR E0321
// It would be unsound for this function to compile.
fn pin_it(not_yet_pinned: &mut PhantomPinned) -> Pin<&mut PhantomPinned> {
Pin::new(not_yet_pinned as &mut dyn MyUnpinTrait).into_pinned_type()
}
fn main() {}

error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `(dyn MyUnpinTrait + 'static)`
--> $DIR/pin-dyn-dispatch-sound.rs:12:1
|
LL | impl Unpin for dyn MyUnpinTrait {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-pinArea: PinC-bugCategory: This is a bug.F-arbitrary_self_types`#![feature(arbitrary_self_types)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundnessneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions