Не приятно, но я бы точно не назвал это ошибкой.
сводится к
class A
class B
implicit def aToB(a: A) : B = a
Нет необходимости, чтобы обе стороны преобразования были связаны каким-либо образом. Неявное - это то же самое, что писать
implicit def aToB(a: A): B = aToB(a)
потому что компилятор вставляет вызов aToB
для преобразования результата a
в требуемый тип возвращаемого значения B
.
Реализация goto 0
- это просто оптимизация хвостового вызова. Компилятор, вероятно, может выдать предупреждение, когда генерирует метод, который запускается таким образом.
Может быть, может существовать правило, согласно которому неявные методы недоступны как имплициты внутри их собственного тела. Но это не всегда создает бесконечный цикл
implicit def listAToListB(l: list[A] = l match {
case Nil => Nil
case x:xs => toB(x) :: xs // equivalent to toB(x) :: listAToList[B](xs)
}
(хорошо, это всего лишь map(toB)
). В любом случае то же самое может произойти с двумя взаимно рекурсивными последствиями. На мой взгляд, не стоит изменять спецификацию, чтобы избежать какой-либо возможности написать бесконечный цикл, ничего не делать, среди многих других. Но было бы неплохо, если бы такой цикл обнаруживался независимо от последствий.