Skip to content

Implement CoerceUnsized and DispatchFromDyn for ManuallyDrop #56193

Open
@mikeyhew

Description

@mikeyhew

Add the following impls:

impl<T: ?Sized, U: ?Sized> CoerceUnsized<ManuallyDrop<T>> for ManuallyDrop<U>
where
    T: CoerceUnsized<U>,
{}

impl<T: ?Sized, U: ?Sized> DispatchFromDyn<ManuallyDrop<T>> for ManuallyDrop<U>
where
    T: DispatchFromDyn<U>,
{}

And add a test case that is allowed by these impls.

This will allow ManuallyDrop<Box<T>> to be unsized to ManuallyDrop<Box<dyn Trait>>, and allow ManuallyDrop<Box<Self>> to be used as a trait-object-safe method receiver with the arbitrary_self_types feature. And similarly for other pointer types besides Box.

Example test case:

trait Trait {
    fn foo(self: ManuallyDrop<Box<Self>>) -> i32;
}

impl Trait for i32 {
    fn foo(self: ManuallyDrop<Box<Self>>) -> i32 {
        self
    }
}

fn main() {
    let x = ManuallyDrop::new(Box::new(5i32)) as ManuallyDrop<Box<dyn Trait>>;
    assert_eq!(x.foo(), 5);
}

This affects stable code, by allowing unsize coercions that were not previously allowed (e.g. from ManuallyDrop<Box<T> to ManuallyDrop<Box<U>> where T: Unsize<U>), so I guess it requires an FCP.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions