Skip to content

Commit f5c64f3

Browse files
committed
Fix #5449: Index class definitions before unpickling parents
Otherwise we may try to unpickle references to these definitions before we have symbols for them (this manifests itself as "undefined: ..." error messages)
1 parent 3dc3b19 commit f5c64f3

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,14 @@ class TreeUnpickler(reader: TastyReader,
869869
val end = readEnd()
870870
val tparams = readIndexedParams[TypeDef](TYPEPARAM)
871871
val vparams = readIndexedParams[ValDef](PARAM)
872+
// It's important to index the class definitions before unpickling the parents
873+
// (see the parents-cycle test for examples where this matter)
874+
val bodyFlags = {
875+
val bodyIndexer = fork
876+
// The first DEFDEF corresponds to the primary constructor
877+
while (bodyIndexer.reader.nextByte != DEFDEF) bodyIndexer.skipTree()
878+
bodyIndexer.indexStats(end)
879+
}
872880
val parents = collectWhile(nextByte != SELFDEF && nextByte != DEFDEF) {
873881
nextUnsharedTag match {
874882
case APPLY | TYPEAPPLY | BLOCK => readTerm()(parentCtx)
@@ -884,7 +892,7 @@ class TreeUnpickler(reader: TastyReader,
884892
else EmptyValDef
885893
cls.info = ClassInfo(cls.owner.thisType, cls, parentTypes, cls.unforcedDecls,
886894
if (self.isEmpty) NoType else self.tpt.tpe)
887-
cls.setNoInitsFlags(parentsKind(parents), fork.indexStats(end))
895+
cls.setNoInitsFlags(parentsKind(parents), bodyFlags)
888896
val constr = readIndexedDef().asInstanceOf[DefDef]
889897
val mappedParents = parents.map(_.changeOwner(localDummy, constr.symbol))
890898

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class A[T]
2+
// Unpickling the parents of B1 will lead to unpickling a call to B1.<init>
3+
class B1 extends A[C1]
4+
class C1 extends B1
5+
6+
// Unpickling the parents of B2 will lead to unpickling a call to the secondary B2.<init>
7+
class B2 extends A[C2] {
8+
def this(x: Int) = this()
9+
}
10+
class C2 extends B2(1)
11+
12+
// Unpickling the parents of B3 will lead to unpickling a call to B3#Hi
13+
class B3 extends A[B3#Hi[Int]] {
14+
type Hi[X] = X
15+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Use {
2+
val b1 = new B1
3+
val b2 = new B2
4+
val b3 = new B3
5+
}

0 commit comments

Comments
 (0)