@@ -149,17 +149,21 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
149
149
// (2) If the parameter accessor reference was to an alias getter,
150
150
// drop the () when replacing by the parameter.
151
151
object intoConstr extends TreeMap {
152
- private var isSuperCall = false
152
+ private var inSuperCall = false
153
153
override def transform (tree : Tree )(using Context ): Tree = tree match {
154
154
case Ident (_) | Select (This (_), _) =>
155
155
var sym = tree.symbol
156
- if sym.is(ParamAccessor ) && (! sym.is(Mutable ) || isSuperCall)
157
- // Variables need to go through the getter since they might have been updated,
158
- // except if we are in a super call, since then the virtual getter call would
159
- // be illegal.
160
- then
156
+ def isOverridableSelect = tree.isInstanceOf [Select ] && ! sym.isEffectivelyFinal
157
+ def keepUnlessInSuperCall = sym.is(Mutable ) || isOverridableSelect
158
+ // If true, switch to constructor parameters only in the super call.
159
+ // Variables need to go through the getter since they might have been updated.
160
+ // References via this need to use the getter as well as long as that getter
161
+ // can be overriddem. This is needed to handle overrides correctly. See run/i15723.scala.
162
+ // But in a supercall we need to switch to parameters in any case since then
163
+ // calling the virtual getter would be illegal.
164
+ if sym.is(ParamAccessor ) && (! keepUnlessInSuperCall || inSuperCall) then
161
165
sym = sym.subst(accessors, paramSyms)
162
- if ( sym.maybeOwner.isConstructor) ref(sym).withSpan(tree.span) else tree
166
+ if sym.maybeOwner.isConstructor then ref(sym).withSpan(tree.span) else tree
163
167
case Apply (fn, Nil ) =>
164
168
val fn1 = transform(fn)
165
169
if ((fn1 ne fn) && fn1.symbol.is(Param ) && fn1.symbol.owner.isPrimaryConstructor)
@@ -170,7 +174,7 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
170
174
}
171
175
172
176
def apply (tree : Tree , prevOwner : Symbol )(using Context ): Tree =
173
- isSuperCall = isSuperConstrCall(tree)
177
+ inSuperCall = isSuperConstrCall(tree)
174
178
transform(tree).changeOwnerAfter(prevOwner, constr.symbol, thisPhase)
175
179
}
176
180
0 commit comments