Skip to content

Commit d995b33

Browse files
authored
Fix Symbol.info remapping in TreeTypeMap (#23432)
Fixes #23279 The issue stems from the fact that in Inlining, when reassigning the owners the inlinined argument (with arg.changeOwner in paramBindingDef), due to a quirk in TypeTreeMap (fixed here), the info field of a `xa` symbol would not be completely remapped, referencing a TypeRef like`defn(correct Symbol, with newly remapped owner).Lifecycle(old and incorrect, with previous owner)`. This info would then be used in `typedValDef` in `erasure` to reassign the ValDef `TypeTree`, referencing the old, incorrect `Symbol` from now on. After that, `LambdaLift` would remap the denotations of class and object `Symbols` found in the tree, while moving their trees outside of methods. Since no class or object definition referenced the old Symbol, that one would not get remapped. So by the time we generated backend code, the `ValDef` TypeTree would reference an incorrect location that no longer existed, causing the runtime error later. The reason why the TypeTreeMap was incorrect was because in situation like this: ```scala final lazy module val lifecycle#7793: lifecycle#7794 = new lifecycle#7794() final module class lifecycle#7794() extends Object#740() { this: lifecycle#7793.type => final lazy module val Lifecycle#7799: Test2$package#3202.lifecycle#7793.Lifecycle#7800 = new Test2$package#3202.lifecycle#7793.Lifecycle#7800() final module class Lifecycle#7800() extends Object#740() { this: lifecycle#7794.this#7794.Lifecycle#7799.type =>} } final lazy module val defn#7795: defn#7796 = new defn#7796() final module class defn#7796() extends Object#740() { this: defn#7795.type => val Lifecycle#7805: lifecycle#7793.Lifecycle#7799.type = lifecycle#7793.Lifecycle#7799 } val xa#7797: defn#7795.Lifecycle#7805.type = defn#7795.Lifecycle#7805 () ``` The remapper would first copy and replace the outermost symbols (including lifecycle#7793, lifecycle#7794, defn#7795, defn#7796, xa#7797), and then separately go through classes definitions. Now we also remap `info` the second time, with the newly mapped nested Symbols.
2 parents d27cf2d + e57d743 commit d995b33

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ class TreeTypeMap(
225225
val tmap1 = tmap.withMappedSyms(
226226
origCls(cls).typeParams ::: origDcls,
227227
cls.typeParams ::: mappedDcls)
228+
mapped.foreach { sym =>
229+
// outer Symbols can reference nested ones in info,
230+
// so we remap that once again with the updated TreeTypeMap
231+
sym.info = tmap1.mapType(sym.info)
232+
}
228233
origDcls.lazyZip(mappedDcls).foreach(cls.asClass.replace)
229234
tmap1
230235
}

tests/run/i23279.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
inline def simpleInlineWrap(f: => Any): Unit = f
2+
3+
@main def Test(): Unit = {
4+
simpleInlineWrap {
5+
object lifecycle {
6+
object Lifecycle {
7+
trait FromZIO
8+
}
9+
}
10+
object defn {
11+
val Lifecycle: lifecycle.Lifecycle.type = lifecycle.Lifecycle
12+
}
13+
val xa: defn.Lifecycle.type = defn.Lifecycle
14+
}
15+
16+
// more nested case
17+
simpleInlineWrap {
18+
object lifecycle {
19+
object Lifecycle {
20+
object FromZIO
21+
}
22+
}
23+
object defn {
24+
val Lifecycle: lifecycle.Lifecycle.type = lifecycle.Lifecycle
25+
}
26+
val xa: defn.Lifecycle.FromZIO.type = defn.Lifecycle.FromZIO
27+
}
28+
}

0 commit comments

Comments
 (0)