Skip to content

ACP: Move ToOwned and Cow to core. #519

@bjoernager

Description

@bjoernager

Proposal

Problem statement

The standard library's alloc crate defines the ToOwned trait and the Cow type in the borrow module. This module is closely tied to Rust's ownership model, and the core crate also defines some facilities in this module (i.e. the Borrow and BorrowMut traits).

Whilst both ToOwned and Cow are usually used in conjunction with the alloc crate's dynamically-allocated types (such as String and Vec), they do not intrinsically need to be coupled with these types.

The issue with having these items in alloc is that it renders it impossible for crates to implement ToOwned for their own types (without, of course, importing either alloc or std). This is despite the fact that it is theoretically possible to define this trait without using any other facilities from alloc or std (the ownership model, at least, exists no matter the combination of crates used).

Motivating examples or use cases

Third-party crates that define their own sense of borrowed vs. owned types would naturally want to implement ToOwned for the borrowed types. But this currently requires importing either of the alloc or std crates, which may not necessarily be wanted (especially if the crate uses the no_std attribute).

Solution sketch

Move the definitions of ToOwned and Cow into core:

// core::borrow;

pub trait ToOwned {
    type Owned: Borrow<Self>;

    fn to_owned(&self) -> Self::Owned;

    fn clone_into(&self, target: &mut Self::Owned);
}

pub enum Cow<'a, B>
where
    B: ToOwned + ?Sized + 'a
{
    Borrowed(&'a B),

    Owned(B::Owned),
}

impl<'a, B> Cow<'a, B> {
    pub fn to_mut(&mut self) -> &mut B::Owned;

    pub fn into_owned(self) -> B::Owned;
}

// Remaining implementations for `Cow`...

As the Cow type is very closely related to ToOwned, I do not see any reason for keeping it separated should ToOwned be moved to core.

Alternatives

Third-party crates could define their own ToOwned or Cow. But this would be completely redundant as the standard items already exist, albeit in an incompatible context.

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-libs-api-nominatedIndicates that an issue has been nominated for discussion during a team meeting.T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions