Suppose we have the following case class and type alias:
scala> case class Foo[A](a: A) defined class Foo scala> type F = Foo[_] defined type alias F
Now we can (not very useful) make a list of things like F :
scala> val foos: List[F] = List(Foo(1), Foo("a"), Foo('a)) foos: List[F] = List(Foo(1), Foo(a), Foo('a))
And we can turn this into an array:
scala> foos.toArray res0: Array[F] = Array(Foo(1), Foo(a), Foo('a))
It is so clear that the compiler can find the manifest that it needs as an implicit argument to the toArray method on the List . But if we ask for a simple old Manifest for F , we get an error:
scala> manifest[F] <console>:11: error: overloaded method value classType with alternatives: (prefix: scala.reflect.Manifest[_],clazz: Class[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and> (clazz: Class[F],arg1: scala.reflect.Manifest[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and> (clazz: Class[_])scala.reflect.Manifest[F] cannot be applied to (java.lang.Class[Foo[_$1]], scala.reflect.Manifest[_$1]) manifest[F]
So it’s clear that the compiler is having problems using the manifest to represent a wildcard in our type alias.
The reason for toArray is that it expects ClassManifest , not just Manifest . And in fact, we can get ClassManifest for F without any problems, precisely because ClassManifest uses OptManifest to represent its type arguments - unlike Manifest , whose type arguments are just other things like Manifest .
scala> classManifest[F] res2: ClassManifest[F] = Foo[<?>]
This <?> Is the string representation of NoManifest . It plays the role of None , allowing the compiler to present class information about type F (which, fortunately, is all we need to create an array) without saying anything about type F arguments outside of "No, I can not model it."