Misunderstanding with Cow::to_mut


#1

Hello,

I would to use Cow<&str> with Serde to avoid extra-allocations.
I decided to learn about Cow and went to read the docs.
I played with Cow::to_mut and noticed strange thing which as I guess means I misunderstand something.

So, we have https://doc.rust-lang.org/std/borrow/enum.Cow.html#method.to_mut with the test inlined.
The test asserts that

assert_eq!(
  cow,
  Cow::Owned(String::from("FOO")) as Cow<str>
);

However, if I make an opposite test it passes too

assert_eq!(
  cow,
  Cow::Borrowed(&String::from("FOO")) // Or just   Cow::Borrowed("FOO") 
);

https://play.rust-lang.org/?gist=3c8abbc8823f037d9fe333b9ec96f664&version=undefined

How is it possible for Cow to be both Borrowed and Owned? Where is a trick here?


#2

The (partial) equality check for Cow is implemented here. You can see that it calls &**self and &**other, which effectively calls the deref implementation on both sides and compares the result.
In the end this means it just compares the contained string values and “FOO” is obviously the same as “FOO”


#3

In addition to what @jer said, it’s important to keep in mind that Cow is a smart pointer. As such, it’s trying to be as “transparent” as possible; its job is to abstract away the borrowed vs owned aspect - it has “no opinion” on the data itself, so to speak, and will delegate to the internal data for other aspects (such as equality).


#4

Yeah, I thought it had something to do with equality traits. I just wasn’t sure which one is used.
As example test misguide me somehow. I thought it was important to compare with right Cow variant.
Thank you!