Skip to content

Commit 7c88469

Browse files
committed
Merge pull request #675 from dotty-staging/fix/#652-erase-constructors
Fix/#652 erase constructors
2 parents f03f5b0 + 8d8942a commit 7c88469

File tree

12 files changed

+55
-10
lines changed

12 files changed

+55
-10
lines changed

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,20 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor
156156

157157
val constrStats, clsStats = new mutable.ListBuffer[Tree]
158158

159+
/** Map outer getters $outer and outer accessors $A$B$$$outer to the given outer parameter. */
160+
def mapOuter(outerParam: Symbol) = new TreeMap {
161+
override def transform(tree: Tree)(implicit ctx: Context) = tree match {
162+
case Apply(fn, Nil)
163+
if (fn.symbol.is(OuterAccessor)
164+
|| fn.symbol.isGetter && fn.symbol.name == nme.OUTER
165+
) &&
166+
fn.symbol.info.resultType.classSymbol == outerParam.info.classSymbol =>
167+
ref(outerParam)
168+
case _ =>
169+
super.transform(tree)
170+
}
171+
}
172+
159173
// Split class body into statements that go into constructor and
160174
// definitions that are kept as members of the class.
161175
def splitStats(stats: List[Tree]): Unit = stats match {
@@ -174,6 +188,8 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor
174188
owner = constr.symbol).installAfter(thisTransform)
175189
constrStats += intoConstr(stat, sym)
176190
}
191+
case DefDef(nme.CONSTRUCTOR, _, ((outerParam @ ValDef(nme.OUTER, _, _)) :: _) :: Nil, _, _) =>
192+
clsStats += mapOuter(outerParam.symbol).transform(stat)
177193
case _: DefTree =>
178194
clsStats += stat
179195
case _ =>
@@ -221,9 +237,15 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor
221237
case stats => (Nil, stats)
222238
}
223239

240+
val mappedSuperCalls = vparams match {
241+
case (outerParam @ ValDef(nme.OUTER, _, _)) :: _ =>
242+
superCalls.map(mapOuter(outerParam.symbol).transform)
243+
case _ => superCalls
244+
}
245+
224246
cpy.Template(tree)(
225247
constr = cpy.DefDef(constr)(
226-
rhs = Block(superCalls ::: copyParams ::: followConstrStats, unitLiteral)),
248+
rhs = Block(mappedSuperCalls ::: copyParams ::: followConstrStats, unitLiteral)),
227249
body = clsStats.toList)
228250
}
229251
}

src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,9 @@ object Erasure extends TypeTestsCasts{
479479
val MethodType(pnames, ptypes) = sym.info.resultType
480480
effectiveSym = sym.copy(info = MethodType(pnames, ptypes, defn.ObjectType))
481481
}
482-
val restpe = effectiveSym.info.resultType
482+
val restpe =
483+
if (effectiveSym.isConstructor) defn.UnitType
484+
else effectiveSym.info.resultType
483485
val ddef1 = untpd.cpy.DefDef(ddef)(
484486
tparams = Nil,
485487
vparamss = (outer.paramDefs(effectiveSym) ::: ddef.vparamss.flatten) :: Nil,

src/dotty/tools/dotc/transform/LambdaLift.scala

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,11 +391,24 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
391391
val freeParamDefs = ownProxies.map(proxy =>
392392
transformFollowingDeep(ValDef(proxy.asTerm).withPos(tree.pos)).asInstanceOf[ValDef])
393393
def proxyInit(field: Symbol, param: Symbol) =
394-
transformFollowingDeep(ref(field).becomes(ref(param)))
394+
transformFollowingDeep(memberRef(field).becomes(ref(param)))
395+
396+
/** Map references to proxy fields `this.proxy` to proxy parameters */
397+
def mapProxies = new TreeMap {
398+
override def transform(tree: Tree)(implicit ctx: Context) = tree match {
399+
case Select(This(_), _) if proxies contains tree.symbol =>
400+
ref(tree.symbol.subst(proxies, ownProxies))
401+
case _ =>
402+
super.transform(tree)
403+
}
404+
}
405+
406+
/** Initialize proxy fields from proxy parameters and map `rhs` from fields to parameters */
395407
def copyParams(rhs: Tree) = {
396408
ctx.log(i"copy params ${proxies.map(_.showLocated)}%, %, own = ${ownProxies.map(_.showLocated)}%, %")
397-
seq((proxies, ownProxies).zipped.map(proxyInit), rhs)
409+
seq((proxies, ownProxies).zipped.map(proxyInit), mapProxies.transform(rhs))
398410
}
411+
399412
tree match {
400413
case tree: DefDef =>
401414
cpy.DefDef(tree)(

src/dotty/tools/dotc/transform/LazyVals.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,16 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
6868
appendOffsetDefs.get(cls) match {
6969
case None => template
7070
case Some(data) =>
71-
cpy.Template(template)(body = data.defs ::: template.body)
71+
cpy.Template(template)(body = addInFront(data.defs, template.body))
7272
}
7373

7474
}
7575

76+
private def addInFront(prefix: List[Tree], stats: List[Tree]) = stats match {
77+
case first :: rest if isSuperConstrCall(first) => first :: prefix ::: rest
78+
case _ => prefix ::: stats
79+
}
80+
7681
/** Replace a local lazy val inside a method,
7782
* with a LazyHolder from
7883
* dotty.runtime(eg dotty.runtime.LazyInt)
File renamed without changes.
File renamed without changes.
File renamed without changes.

tests/pending/run/constructors.scala renamed to tests/run/constructors.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ class A(x: Int, y: Int) {
44
def this(x: Int) = this(x, x);
55
def this() = this(1);
66
override def toString() = "x=" + x + " y=" + y;
7-
class B(a: Int, b: Int, c: String) {
7+
class B(val a: Int, b: Int, c: String) {
88
def this(str: String) = this(x, y, str);
9+
val xx = a
910
override def toString() =
1011
"x=" + x + " y=" + y + " a=" + a + " b=" + b + " c=" + c;
1112
}

tests/pending/run/shortClass.check renamed to tests/run/shortClass.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
bippity.bop.Foo
22
bippity.bop.Foo$Bar
33
bippity.bop.Foo$Bar$
4-
Test$$anon$1
5-
Test$$anon$2
4+
Test$$anon$
5+
Test$$anon$
66
Foo
77
Bar
88
Bar$

tests/pending/run/shortClass.scala renamed to tests/run/shortClass.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ object Test {
1515
import bippity._
1616
import bop._
1717

18+
def printSanitized(x: String) = println(x.filterNot(_.isDigit))
19+
1820
def main(args: Array[String]): Unit = {
1921
val f = new Foo
2022
val instances = List(f, new f.Bar, f.Bar, new Foo with DingDongBippy, new f.Bar with DingDongBippy)
21-
instances map (_.getClass.getName) foreach println
22-
instances map shortClassOfInstance foreach println
23+
instances map (_.getClass.getName) foreach printSanitized
24+
instances map shortClassOfInstance foreach printSanitized
2325
}
2426
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)