Skip to content

PinCoerceUnsized has strange impls #145081

@theemathas

Description

@theemathas

The PinCoerceUnsized type allows unsize-coercing through Pin.

I found that PinCoerceUnsized has the following impls in the standard library, which are on types that don't even implement Deref, and therefore are useless within a Pin.

unsafe impl<T: ?Sized> PinCoerceUnsized for *const T {}
unsafe impl<T: ?Sized> PinCoerceUnsized for *mut T {}
unsafe impl<T: PointeeSized> PinCoerceUnsized for NonNull<T> {}

unsafe impl<T: ?Sized> PinCoerceUnsized for UnsafeCell<T> {}
unsafe impl<T: ?Sized> PinCoerceUnsized for SyncUnsafeCell<T> {}
unsafe impl<T: ?Sized> PinCoerceUnsized for Cell<T> {}
unsafe impl<T: ?Sized> PinCoerceUnsized for RefCell<T> {}

unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for alloc::rc::Weak<T, A> {}
unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for alloc::sync::Weak<T, A> {}

I don't see any point on why these would be allowed. These impls allows some really strange code to compile in stable rust. For example, the following code compiles:

use std::cell::UnsafeCell;
use std::pin::Pin;

fn foo(x: Pin<UnsafeCell<&i32>>) -> Pin<UnsafeCell<&dyn Sync>> {
    x
}

fn bar(x: Pin<&i32>) -> Pin<*const dyn Send> {
    x
}

Notably, despite bar compiling, it is not allowed to coerce a Pin<&i32> to a Pin<*const i32>.

I'm not sure if these strange behaviors have any soundness implications. (Although the impl on the cell types worryingly lack a T: PinCoerceUnsized bound). But since they serve no purpose, can they be deleted?

@rustbot labels +A-pin +A-coercions

Meta

The code snippets are tested on the playground with version 1.91.0-nightly (2025-08-07 2fd855fbfc8239285aa2)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coercionsArea: implicit and explicit `expr as Type` coercionsA-pinArea: PinC-bugCategory: This is a bug.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions