Skip to content

Commit 7983a2f

Browse files
committed
Fix variable handling in super calls
Accesses to var parameters in super calls need to refer to the constructor parameter, not the getter. Fixes #13630
1 parent ffd9471 commit 7983a2f

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

compiler/src/dotty/tools/dotc/transform/Constructors.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,16 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
146146
// (2) If the parameter accessor reference was to an alias getter,
147147
// drop the () when replacing by the parameter.
148148
object intoConstr extends TreeMap {
149+
private var isSuperCall = false
149150
override def transform(tree: Tree)(using Context): Tree = tree match {
150151
case Ident(_) | Select(This(_), _) =>
151152
var sym = tree.symbol
152-
if (sym.is(ParamAccessor, butNot = Mutable)) sym = sym.subst(accessors, paramSyms)
153+
if sym.is(ParamAccessor) && (!sym.is(Mutable) || isSuperCall)
154+
// Variables need to go through the getter since they might have been updated,
155+
// except if we are in a super call, since then the virtual getter call would
156+
// be illegal.
157+
then
158+
sym = sym.subst(accessors, paramSyms)
153159
if (sym.maybeOwner.isConstructor) ref(sym).withSpan(tree.span) else tree
154160
case Apply(fn, Nil) =>
155161
val fn1 = transform(fn)
@@ -161,6 +167,7 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
161167
}
162168

163169
def apply(tree: Tree, prevOwner: Symbol)(using Context): Tree =
170+
isSuperCall = isSuperConstrCall(tree)
164171
transform(tree).changeOwnerAfter(prevOwner, constr.symbol, thisPhase)
165172
}
166173

tests/run/i13630.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
it worked

tests/run/i13630.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class ClassWithLambda(sup: () => Long)
2+
class ClassWithVar(var msg: String) extends ClassWithLambda(() => 1)
3+
4+
object Test:
5+
val _ = new ClassWithVar("foo")
6+
7+
def main(args: Array[String]): Unit = {
8+
println("it worked")
9+
}

0 commit comments

Comments
 (0)