Skip to content

Intended semantics of abstract types and projections vs SLS  #4612

Closed
@Blaisorblade

Description

@Blaisorblade

To me (and to @milessabin in #4583 and scala/bug#10916), type projections of abstract types are meant to be, indeed, abstract types between their bounds.
But the SLS says that Derived <: Base implies Derived#A <: Base#A. Hence, if Base#A >: S <: U, I can ensure that Base#A = U by defining a subclass with Derived#A = U to ensure that Base#A >: Derived#A = U. That fails in Scalac but works in Dotty, yet it doesn't have justification in either the intended semantics or in the nuObj paper. On the other hand, if that's meant to actually hold, it should be part of type equality — while right now you can only witness this indirectly.

scala> trait Base { type A }
// defined class Base

scala> class Derived extends Base { type A = Any }
// defined class Derived

scala> def cast(x: Any): A#T = (x: B#T): A#T
def cast(x: Any): A#T

scala> def cast2(x: Any): A#T = x: A#T
1 |def cast2(x: Any): A#T = x: A#T
  |                         ^
  |                         found:    Any(x)
  |                         required: A#T
  |

Relatedly, I've long been concerned that underlying on TypeBounds returns the upper bound, even though one would think that tp.underlying is always meant to be =:= tp.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions