IDEA is simply confused because of the { } block. None of these codes even exist at runtime.
Here is a small example. General identification method for types with one type argument:
def id[F[_], A](value: F[A]) = value
It is not possible to call this method with a type that takes two type arguments:
class Test[A, B] id(new Test[Int, Int]) <console>:10: error: type mismatch; found : Test[Int,Int] required: F[A] id(new Test[Int, Int])
But we can use the lambda type to define the id2 function, which is implemented in terms of id:
def id2[F[_, _], A, B](value: F[A, B]) = id[({ type f[x] = F[A, x] })#f, B](value) id2(new Test[Int, Int]) res3: Test[Int,Int] = Test@1a53ac0c
Pretty confusing, but it works. Now look at the bytecode.
scala> :javap -c id2 ... public <F, A, B> F id2(F); Code: 0: getstatic #19
As you can see, nothing remains of all the type tricks. No reflection, nothing. Just java.lang.Object .