Dotty: 3.0.0-Mx: Variable argument in constructor corrupts captured variables in super-constructor call.

Created on 9 Jan 2021  路  1Comment  路  Source: lampepfl/dotty

Minimized code

abstract class Foo(x: Any)
class Boom(var x: Unit, y: Unit) extends Foo((x: Int) => x)

The key conditions to trigger this bug seem to be having a variable in the constructor, and an argument after it, and the arguments to the super type must attempt to capture the arguments of the constructor.

Output

This causes a crash about not being able to unify two variables. In fact, it also dumps the desuagared source file:

class Boom(x: Unit, y: Unit) extends Foo(
  Boom#Boom$superArg$1(this.x, this.x_=)
) {
  def x: Unit
  def x_=(x$1: Unit): Unit
  private val y: Unit
  private <static> def Boom$superArg$1(x: Unit, y: Unit): Int => Int =
    {
      def $anonfun(x: Int): Int = x
      closure($anonfun)
    }
}

The problem is really obvious in this snippet: superArg$1(this.x, this.x_=) is clearly not the expected superArg$1(this.x, this.y)
and, clearly, Unit => Unit, expected Unit is the jist of the mangled type-error .

This can be reproduced on scastie targeting 3.0.0-M3, but it appears this bug still exists all the way back to 0.27.0-RC1 and possibly even earlier than that!

It looks as if the compiler insert arguments into these closures in some form of list, and that list is being polluted with the generated setter, pushing out another legitimate argument.

bug

Most helpful comment

Thanks for the diagnosis! With findings so detailed the bug almost fixed itself. 馃槃

>All comments

Thanks for the diagnosis! With findings so detailed the bug almost fixed itself. 馃槃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

noti0na1 picture noti0na1  路  3Comments

liufengyun picture liufengyun  路  3Comments

Blaisorblade picture Blaisorblade  路  3Comments

odersky picture odersky  路  3Comments

milessabin picture milessabin  路  3Comments