Вот сокращенный пример кода, который выдает ту же ошибку,
class Foo(t: Any)
class Bar(x: String = "bar")
object Bar extends Foo(new Bar())
// ^
// Error, super constructor cannot be passed a self reference unless
// parameter is declared by-name
Байт-код помогает объяснить, что происходит. Из REPL,
scala> class Foo(t: Any)
scala> class Bar(x: String = "bar")
scala> :javap -v Bar
Compiled from "<console>"
public class Bar extends java.lang.Object implements scala.ScalaObject
...
{
public Bar(java.lang.String);
...
Мы видим, что класс Bar
имеет только один конструктор, который принимает параметр String
. Но мы знаем, что Bar
также имеет конструктор, который использует значение по умолчанию x = "bar"
, откуда оно берется?
scala> :javap -v Bar$
...
public java.lang.String init$default$1();
Code:
Stack=1, Locals=1, Args_size=1
0: ldc #16; //String bar
2: areturn
LineNumberTable:
line 7: 0
Ах, это определено в объекте-компаньоне, который принадлежит классу Bar$
(об этом должен знать только компилятор Scala).
Похоже, что в extends Foo(new Bar())
вы пытаетесь получить доступ к методу в объекте Bar
во время инициализации суперкласса Bar
(который находится перед объектом Bar
фактически построен).
Если это не ошибка в компиляторе Scala, это ошибочное сообщение об ошибке! Я не могу сказать, какой. Я подал проблему SI-5000 в трекер ошибок.
В качестве обходного пути вы можете избежать значения по умолчанию: object Bar extends Foo(new Bar("bar"))
.