Open coreywoodfield opened 1 year ago
This used to compile in 3.0.0. However we cannot really call this a regression as it produced invalid bytecode that caused a crash at runtime
import scala.reflect.ClassTag
abstract class Companion[C](implicit val ct: ClassTag[C])
case class Impl()
object Impl extends Companion[Impl]
object Main {
def main(args: Array[String]) =
println(Impl)
}
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
Impl$.<init>()V @2: invokevirtual
Reason:
Type uninitializedThis (current frame, stack[1]) is not assignable to 'Impl$'
Current Frame:
bci: @2
flags: { flagThisUninit }
locals: { uninitializedThis }
stack: { uninitializedThis, uninitializedThis }
Bytecode:
0x0000000: 2a2a b600 15b7 0018 b1
at Main$.main(Circular.scala:10)
at Main.main(Circular.scala)
Here's what I'm thinking: maybe in typedImplicit
we can return a failure result if the implicit candidate we're considering is on a companion object Impl, while compiling (through ctx.owner) the constructor of object Impl. Then we just need to exempt if pt
is by-name, which I assume needs to work seeing as CheckNoSuperThis
makes reference to by-name implicits.
The workaround is explicitly passing ClassTag[Foo](classOf[Impl])
, which seems reasonable.
Compiler version
3.2.1
Minimized code
Output
Expectation
It's trying to use
Impl.ct
as the implicit value to pass to the super constructor, but that obviously doesn't work. I would expect this to get the implicitClassTag
from wherever implicitClassTag
s are normally gotten from. This works fine in scala 2. Removing theval
also fixes it, but then you don't have theClassTag
field