Skip to content

Commit

Permalink
Rollup merge of #125072 - Darksonn:pin-dyn-dispatch-sound, r=jhpratt
Browse files Browse the repository at this point in the history
Add test for dynamic dispatch + Pin::new soundness

While working on [the `#[derive(SmartPointer)]` RFC][1], I realized that the soundness of <code>impl [DispatchFromDyn](https://doc.rust-lang.org/stable/std/ops/trait.DispatchFromDyn.html) for [Pin](https://doc.rust-lang.org/stable/std/pin/struct.Pin.html)</code> relies on the restriction that you can't implement [`Unpin`](https://doc.rust-lang.org/stable/std/marker/trait.Unpin.html) for trait objects.

As far as I can tell, the relevant error exists to solve some unrelated issues with coherence. To avoid cases where `Pin` is made unsound due to changes in the coherence-related errors, add a test that verifies that unsound use of `Pin` and `DispatchFromDyn` does not become allowed in the future.

[1]: rust-lang/rfcs#3621
  • Loading branch information
jhpratt authored May 14, 2024
2 parents 18d9c03 + b3a78c1 commit 209703a
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
19 changes: 19 additions & 0 deletions tests/ui/coercion/pin-dyn-dispatch-sound.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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() {}
9 changes: 9 additions & 0 deletions tests/ui/coercion/pin-dyn-dispatch-sound.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
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

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0321`.

0 comments on commit 209703a

Please sign in to comment.