Using generics with impl

#[derive(Debug)]
struct Test<T>
{
    x:      T,
    y:      T,
}

impl Test<T> // Error over here
{
    
}

fn main()
{
    let test = Test{x: 10., y: 20.};
    println!("{:?}", test);
}

How come with generics for impl I have to write it like this:

impl<T> Test<T>
{
    
}

I don't quite get that?

A generic on the impl means "duplicate this impl for every possible choice of generic types". When there is no generic, it is instead used for specific types.

impl Test<f64> {
    fn len(&self) -> f64 {
        (self.x * self.x + self.y * self.y).sqrt()
    }
}

The above block defines a method for only a specific type parameter.

So if you write impl Test<T>, you are referring to a specific type of type name T, but with impl<Foo> Test<Foo> you are referring to all types in place of Foo.

1 Like

You can think of it analogously to regular variables: you have to declare your variables first, and only then can you use them:

impl<T> Test<T> { /* ... */ }
    ^^^ ^^^^^^^
     |     |
     +- - -|- - - - - Type variable declarations
           |
           +- - - - - A compound type that uses the variables

The declaration is necessary to resolve conflicts between generic type names and concrete type names:

struct T { /* ... */ }

/// These definitions are only valid if `Test` contains the struct above
impl Test<T> { /* ... */ }

/// These definitions are valid for any inner type
impl<T> Test<T> { /* ... */ }

/// This is an error because you declare a variable that isn’t used
impl<T> Test<f64> { /* ... */ }
2 Likes