Search code examples
scalagenericstype-members

Referencing generic type parameter shadowed by abstract type member


Is there a way to reference a generic type parameter that is shadowed by an abstract type member of the same name?

Suppose we have a trait and extending class:

trait Foo {
    type T
    var get: T = _
}

class Bar[X] extends Foo {
    override type T = X //We can set the type member by referencing the generic parameter X
}

class Baz[T] extends Foo {
    override type T = ??? //How can we reference the generic parameter T here?
}

Obviously it's usually not a big deal to just name the generic parameter different than the type member, but this isn't always the best option (for example, when using an external library). Is there a way to reference the shadowed generic parameter? Where in the Scala spec is this interaction between type members and generic parameters delineated?


Solution

  • Even without overriding the trait's abstract member, the type T will always refer to the inherited type member, and not the generic parameter. This is a known issue, filed as SI-8421. From the proposed fix, it is explained why this is a bug:

    When binding a name to a symbol, we search up through the context chain. At each step, we first look in the current scope. If that fails, we look for members of the prefix of the closest enclosing context associated with a Template or PackageDef.

    However, this means we will look for an inherited type member before finding an eponymous class type parameter, which is in the scope of an enclosing context two levels out.

    So maybe after that issue is resolved (marked for 2.12.0-M2), it will become possible to reference the shadowed type, even if the abstract type member is overriden.