Почему в этом Scala кодексе необходимо повышение?

Это компилируется:

import scala.collection._

trait Foo[A, +This <: SortedSet[A] with SortedSetLike[A,This]]
extends SortedSetLike[A, This] { this: This =>

  def bar: This = (this: SortedSetLike[A,This]).empty

}

Но если удаленный файл удаляется, он не скомпилируется:

import scala.collection._

trait Foo[A, +This <: SortedSet[A] with SortedSetLike[A,This]]
extends SortedSetLike[A, This] { this: This =>

  def bar: This = this.empty

}

Почему? Из предложения extends мы знаем, что Foo - это SortedSetLike[A, This], поэтому, конечно, upcast действительно - но разве это не показывает, что компилятор разрешил конфликтующее наследование?

Ответ 1

Свойство SortedSetLike наследует пустой метод из SetLike.

/** The empty set of the same type as this set
* @return  an empty set of type `This`.
*/
def empty: This

Но SortedSet переопределяет пустой метод и имеет явный тип возвращаемого значения:

/** Needs to be overridden in subclasses. */
override def empty: SortedSet[A] = SortedSet.empty[A]

Поскольку вы указываете, что Этот является подклассом SortedSet, компилятор найдет SortedSet реализацию пустого первого, который вернет SortedSet. Компилятор не знает, как преобразовать полученный SortedSet в ваш Этот подкласс.

Но если вы повышаете до уровня SortedSetLike, компилятор найдет свой пустой метод, который возвращает This.