I guess that in the given code following things happen:
// R is erased totally, so asInstanceOf does nothing in runtime, but still affects scalac typechecker def execute[R](): R = (new Object).asInstanceOf[R] // scalac sees that execute[Int]() returns Int, which is not a subclass of Unit, so it must drop it val r1: Unit = execute[Int]() // scalac sees that execute[Nothing]() returns Nothing, which is a subclass of Unit, so it tries to use it as Unit val r2: Unit = execute[Nothing]() // scalac sees that execute[Unit]() returns Unit, so it tries to use it as Unit val r3: Unit = execute[Unit]()
Therefore there’s no bug in the compiler. Instead, there’s a bad combination of type erasure and runtime type casts.
I’ll guess again. My hunch is that discarding the value is tried only after assignment doesn’t typecheck. Is that useful at all? I don’t know.