Smart pointer which owns its target

Why is Deref a supertrait of IntoOwned

On IRLO, there was some reservation in regard to the idea of making IntoOwned: Deref. I'd like to give a short explanation why I think it should be:

IntoOwned is not a generic conversion from a type into an owned type. IntoOwned should be more understood as RefIntoOwned or RefWhichManagesOwnershipIntoOwned. These reference-like types are:

  • &'a T (always borrowed)
  • Cow<'a, T> (sometimes borrowed, sometimes owned, determined at run-time)
  • Owned<T> (always owned)

IntoOwned can still be used to go from some non-owned type like str to String. This is because IntoOwned is implemented for &str:

use std::borrow::{Borrow, Cow};
use std::ops::Deref;

pub trait IntoOwned: Sized + Deref {
    type Owned: Borrow<<Self as Deref>::Target>;
    fn into_owned(self) -> Self::Owned;
}

impl<'a, T> IntoOwned for &'a T
where
    T: ?Sized + ToOwned,
{
    type Owned = <T as ToOwned>::Owned;
    fn into_owned(self) -> Self::Owned {
        self.to_owned()
    }
}

fn main() {
    let hello: &str = "Hello World!";
    let owned: String = hello.into_owned();
    println!("{owned}");
    let cow_borrowed: Cow<'static, str> = Cow::Borrowed("I'm a cow.");
    let my_own_cow: String = cow_borrowed.into_owned();
    println!("{my_own_cow}");
}

(Playground)

Output:

Hello World!
I'm a cow.


Oooops… in the above Playground I accidentally used Cow::into_owned, which is also a method of the enum (not a trait method) having the same name and doing the same in that case. But it works as trait method of IntoOwned as well, see fixed Playground.