scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

Unnecessary field in subclass, parameter alias not detected #12995

Open lrytz opened 6 months ago

lrytz commented 6 months ago

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 commented 6 months ago

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

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).