Skip to content

Commit 401323c

Browse files
authored
Merge pull request #13639 from dotty-staging/fix-13630
Fix variable handling in super calls
2 parents e26a028 + 0210ad8 commit 401323c

File tree

5 files changed

+23
-6
lines changed

5 files changed

+23
-6
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/neg/i11045.scala

Lines changed: 0 additions & 5 deletions
This file was deleted.

tests/run/i11045.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
abstract class Foo(x: Any)
2+
class Boom(var x: Unit, y: Unit) extends Foo((x: Int) => x) // was error: super constructor cannot be passed a self reference
3+
@main def Test =
4+
Boom((), ())
5+

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)