You have to look at the following line as two separate parts, the left hand side of the = and the right:
val oB: Option[B] = collectFirstOf(List(new A,new B))
What you're expecting here is that the type of the collectFirstOf expression (the rvalue) should be inferred from the type of the value oB. The compiler can't do this. You have to say specifically what type you're expecting. Take the following example:
val v: Long = 1 + 4
The type of the expression 1 + 4 is an Int. This int is then converted into a Long. The compiler doesn't, and can't infer that you want the 1 or the 4 to be Long:
So, to fix your problem, you need to tell the compiler what type you're expecting, otherwise it assumes java.lang.Object:
val oB = collectFirstOf[B](List(new A,new B))
So the manifest gets correctly assigned, and all is well with the world. So why does the following even compile:
val oB:Option[B] = collectFirstOfT(List(new A,new B))
oB: Option[B] = Some(A@10f3a9c)
at first sight, it doesn't seem like this should work, but it does. This is because the collectFirstOfT actually returns an Option[Nothing], which can be safely converted to a Option[B]:
scala> val f = collectFirstOfT(List(new A,new B))
f: Option[Nothing] = Some(A@baecb8)
scala> f.asInstanceOf[Option[B]]
res4: Option[B] = Some(A@baecb8)