Since you are not explicitly populating T, the compiler is trying to pass it to you with suitable types to make this compiler:
animalCarer.display[testing.ParamTest.Animal](ParamTest.this.puppy1);
animalCarer.display[testing.ParamTest.Puppy](ParamTest.this.puppy2);
animalCarer.display[testing.ParamTest.Animal](ParamTest.this.dog)
This is part of the Scala Local Type Inference algorithm . As you can see, each method call is displayed on the right T, for example puppy1: Animal, which adheres to a lower bound.
source
share