I've been learning on rust smart pointers and collections, and there is a question stucked in my mind. Why Rust' Box, Rc, Arc don't implement Borrow for its internal type like this:
impl<T, Q: ?Sized> Borrow<Q> for Box<T>
where
T: Borrow<Q>
{
...
}
For context, I'm working with HashMap<Rc<String>,i32>. And I want to do something like this:
let m: HashMap<Rc<String>,i32> = ...;
let k: &str = "some_sring";
m.get(k); // this fails
It seems the m.get(k) is failing because Rc<String> doesn't implement Brrow<str>, and it only implements Borrow<&String>. So I need to convert my &str to String in order to use it. I'm ok with this limitation. But, I want to know why does this is the case, and I want to know if I'm missing something.
And also Box is #[fundamental], which means you can implement traits for Box<LocalType> like you can for LocalType, so adding it for Box specifically would be a breaking change.
I think the conflict is legit without considering #[fundamental] anyway though... yep, it is.
Interesting, I didn't know we can use Rc like this. This seems better, thank you.
Yeah, I noticed this, and it makes sense.
But, I spend quite some time thinking why we ca't do something like this:impl Borrow<Q> for Box<T> where T != Q, T: Borrow<Q> and make it non-conflicting with impl Borrow<T> for Box<T>.
Though really, the problem is only with blanket implementations. Various covered implementations for combinations of std types could be added, which I guess is what this issue is about.
Many combinations of the existing stdBorrow implementations would be variations on the impl Borrow<UnsizedThing> for Box<SizedThing> though, to which the answer is probably "just use Box<UnsizedThing> instead", as with your Rc<str> case.