Trait tells everything by the type

What confused me when I was a beginner

When I started to learn Rust what was confusing to me was implementation notations like

impl XXX for [T]

I already knew that the type [T] is not a type we can access directly but we need some pointer instead to it to access it. So my natural question was why it wasn't

impl XXX for &[T]

because implementing for types that is close to our usage should mean more.

Traits are responsible for the controlling ownership and reference of types

For Rust, & or &mut are part of the types. That is the reason why traits want to control the ownership/reference and mutability in their own definitions like

  • This function doesn't mutate anything.
  • This function needs ownership.

Since these properties are given by the trait and the responsibility of the traits, the implementor doesn't need to care about it and we have less chance to implement for pointer types. For programmers, the simple thing that Rust compiler does is replace the self type by the type itself.

For example, let's think about Index trait

pub trait Index<Idx: ?Sized> {
    type Output: ?Sized;
    fn index(&self, index: Idx) -> &Self::Output;

one of its implementations impl<T, I> Index<I> for [T] means you must implement a function with type

fn index(&[T], index: I) -> &Self::Output

Trait tells everything by the type definition

Having known this fact we now know that we can know everything what traits want to do from their own types. For example, we can know that Deref trait is to convert some reference to reference

pub trait Deref {
    type Target: ?Sized;
    fn deref(&self) -> &Self::Target;

and Into trait converts some ownership into another ownership.

pub trait Into<T>: Sized {
    /// Performs the conversion.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn into(self) -> T;

You don't need to think of using impl Into<&Target> for &T as an alternative to Deref trait but can leave everything about the reference stuffs to the trait definition.