Missing From<&T> for T where T: Clone implementation?


#1

Into<String> is super handy for passing in either a &str or a String to a function that ultimately wants an owned String, and I expected this to be generalized to all types that implement Clone, so that I can write functions that can take either moved values or a reference to a value with a clone. It seems that there is no From<&T> for T where T: Clone implementation though - why? Is there some underlying reason why this wasn’t implemented, or is it an oversight?

There is an implementation of ToOwned<T> for T where T: Clone, but obviously that wouldn’t work for moving values.


#2

This is usually achieved using Cow. You can take a Cow by value as an argument, and call into_owned on it if you want to pull the underlying value out. Typically you just work with the Cow as a smart wrapper around the underlying value (or reference) though.

Also, Borrow can be used as the generic type bound to allow generic functions to work over owned or borrowed values transparently. It also allows borrowing to a different type (e.g. borrow String as &str rather than &String).


#3

Could it be the case that From<&T> for T would conflict with a lot of existing, more specific trait implementations?

(Sidenote, basing it on ToOwned would make it more general)


#4

I thought about that too, but can’t see how that differs from some of the existing reflexive blanket impls that someone could, in theory, customize/specialize.

And I also agree that ToOwned seems like the right concept to generalize.


#5

Compatibility wise, it’s a breaking change to add a new blanket implementation for T, &T, &mut T, Box<T> for a trait. Since this case involves multidispatch (the From<&T> part), I don’t know off hand.


#6

Yeah, compatibility is a concern nowadays but I think @Xenopathic’s question was also more of “was this an oversight originally” type of thing.

In terms of ToOwned, although the name of the trait matches what we’re talking about, ToOwned::to_owned takes &self. That doesn’t really match what’s needed. How would one implement it? It cannot return self since it’s also borrowing self. So in that sense, From is probably the right path.