Skip to content

The "method references Self" object-safety rule is overly restrictive #47649

@mikeyhew

Description

@mikeyhew

Is there any reason why the following trait method can't be object safe?

trait Trait {
    fn take_and_return_box(self: Box<Self>) -> Box<Self>;
}

Intuitively, it would return Box<T> when called on a Box<T> where T: Trait, and Box<Trait> when called on a Box<Trait>. The compiler would do an unsize coercion on the Box<T> returned by the vtable method, combining it with the vtable of the Box<Trait> that was passed in.

If I'm not mistaken, the object safety rule could be relaxed to allow methods that reference the Self type in the return value, as long as it's a type that meets certain CoerceUnsized requirements:

  • Let ReturnType<Self> be the return type of the method, e.g. Box<Self>
  • For a given type T, let ReturnType<T> be ReturnType<Self> with every occurrence of Self replaced with T
  • The trait method is object safe if the following conditions are met:
    • ReturnType<Trait>: Sized
    • for every type T: Unsize<Trait>, ReturnType<T>: CoerceUnsized<Trait>.

Note: this is very similar to what I think the object-safety rules for arbitrary_self_types (#44874) will look like

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-dyn-traitArea: trait objects, vtable layoutA-trait-systemArea: Trait systemC-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language teamT-typesRelevant to the types 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