Search code examples
scalaimplicit

Why does implicitly[ClassTag[T]] resolve successfully?


In the following simplest example I have no compile errors:

object App {
  def main(args: Array[String]) = {
    test[Int]()
  }
  def test[T <: Int : ClassTag]() = println(implicitly[ClassTag[T]])
}

the program prints Int. But I don't understand why an object of type ClassTag[T] can be found for implicitly[ClassTag[T]] invocation? the only thing I did was to provide generic type argument. Where does the ClassTag[Int] come from?


Solution

  • The : symbol defines a context bound, which means that the compiler has to have an instance of ClassTag[T] in its implicit scope. It's syntactic sugar for the following:

    def test[T <: Int]()(implicit $ev: ClassTag[T]) = println(implicitly[ClassTag[T]])
    

    The call to implicitly will then take $ev as the required instance.

    But this of course pushes the question a little bit further: where does the $ev (evidence) come from? To quote the Scala documentation (referring to TypeTag, but the same applies to ClassTag):

    Given context bound [T: TypeTag], the compiler will simply generate an implicit parameter of type TypeTag[T] and will rewrite the method to look like the example with the implicit parameter in the previous section.