Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does `Borrow` work without trait specialization?

Tags:

rust

traits

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?

like image 975
Lukas Kalbertodt Avatar asked Oct 25 '15 19:10

Lukas Kalbertodt


1 Answers

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>
like image 195
aochagavia Avatar answered Feb 23 '23 15:02

aochagavia