bug
bug copied to clipboard
Unnecessary field in subclass, parameter alias not detected
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.
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
superAccis the fieldB.idsuperAcc.initialize.aliasis the getterA.idsuperClazz.info.nonPrivateMember(alias.name)gives the getter overrideB.id, which is notA.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).