bug icon indicating copy to clipboard operation
bug copied to clipboard

Unnecessary field in subclass, parameter alias not detected

Open lrytz opened this issue 1 year ago • 1 comments

On 2.13.14

abstract class A(val id: String)

// `B.id` has alias `A.id`, no field in `B`
abstract class B(override val id: String) extends A(id)

// `idC` has no alias, unnecessary field in `C`
class C(idC: String) extends B(idC) { def m = idC }

Class C gets a field. If B's parameter has a different name aliasing is identified, C gets no field.

lrytz avatar May 06 '24 12:05 lrytz

The issue is here https://github.com/scala/scala/blob/v2.13.14/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L6554

        val superClazz = sym.superClass

          superAcc.initialize.alias // Is the param accessor is an alias for a field further up  the class hierarchy?
            orElse (superAcc getterIn superAcc.owner) // otherwise, lookup the accessor for the super
            filter (alias => superClazz.info.nonPrivateMember(alias.name) == alias) // the accessor must be public
  • superAcc is the field B.id
  • superAcc.initialize.alias is the getter A.id
  • superClazz.info.nonPrivateMember(alias.name) gives the getter override B.id, which is not A.id, so the alias is discarded

Maybe it's an overisght, we could change it to alias.owner.info.nonPrivateMember; but I'm not entirely sure because the generated bytecode is INVOKESPECIAL A.id (super call to A.id), but we have C extends B extends A, where B overrides id. Would need to dig to know if that's valid.

On the other hand, generating a super call instead of a virtual call might a bug on its own (https://github.com/scala/bug/issues/9330#issuecomment-2095908600).

lrytz avatar May 06 '24 13:05 lrytz