Lukas Kalbertodt
Lukas Kalbertodt

Reputation: 88556

How does `Borrow` work without trait specialization?

Currently, Rust does not have the feature "trait specialization" yet. As far as I understand, this means that a trait can't be implemented more than once for one given type. However, I noticed that the Borrow trait is implemented for T where T: ?Sized which are all non-reference types there are (right?). But it's also implemented for several other types, like Vec<T>, which looks like a specialization.

How is that working? Is it compiler magic or did I misunderstand what trait specialization is?

Upvotes: 7

Views: 171

Answers (1)

aochagavia
aochagavia

Reputation: 6236

Short answer

In this case, trait specialization is not necessary, since the implementations are non-overlapping.

Long answer

In the particular case of Vec<T>, there are many impls that apply to it. For instance, the following:

impl<T> Borrow<T> for T where T: ?Sized
impl<'a, T> Borrow<T> for &'a T where T: ?Sized
impl<'a, T> Borrow<T> for &'a mut T where T: ?Sized
// other implementations are omitted for conciseness

According to those implementations, the compiler can deduce the following:

  1. Vec<T> implements Borrow<Vec<T>>
  2. &'a Vec<T> implements Borrow<Vec<T>>
  3. &'a mut Vec<T> implements Borrow<Vec<T>>

However, none of them implements Borrow<[T]> for Vec<T>. Since that implementation is not provided, you are free to provide your own:

impl<T> Borrow<[T]> for Vec<T>

Upvotes: 7

Related Questions