Skip to content

Commit ea29eaf

Browse files
oderskyallanrenucci
authored andcommitted
More robust scheme to add tuple members
Previous scheme did not work if fixed completer was subsequently overridden by another completer. The new scheme goes directly to the places where parents are computed in various completers.
1 parent 5db3c5d commit ea29eaf

File tree

4 files changed

+16
-31
lines changed

4 files changed

+16
-31
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,8 @@ class Definitions {
939939
def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = scalaClassName(ref.classSymbol)
940940

941941
private def isVarArityClass(cls: Symbol, prefix: String) =
942-
scalaClassName(cls).testSimple(name =>
942+
cls.isClass && cls.owner.eq(ScalaPackageClass) &&
943+
cls.name.testSimple(name =>
943944
name.startsWith(prefix) &&
944945
name.length > prefix.length &&
945946
name.drop(prefix.length).forall(_.isDigit))
@@ -1159,6 +1160,14 @@ class Definitions {
11591160
def isAssuredNoInits(sym: Symbol) =
11601161
(sym `eq` SomeClass) || isTupleClass(sym)
11611162

1163+
/** If `cls` is Tuple1..Tuple22, add the corresponding *: type as last parent to `parents` */
1164+
def adjustForTuple(cls: ClassSymbol, tparams: List[TypeSymbol], parents: List[Type]): List[Type] = {
1165+
def syntheticParent(tparams: List[TypeSymbol]): Type =
1166+
if (tparams.isEmpty) TupleTypeRef
1167+
else (tparams :\ (UnitType: Type)) ((tparam, tail) => PairType.appliedTo(tparam.typeRef, tail))
1168+
if (isTupleClass(cls) || cls == UnitClass) parents :+ syntheticParent(tparams) else parents
1169+
}
1170+
11621171
// ----- primitive value class machinery ------------------------------------------
11631172

11641173
/** This class would also be obviated by the implicit function type design */
@@ -1260,27 +1269,6 @@ class Definitions {
12601269

12611270
private[this] var isInitialized = false
12621271

1263-
/** Add a `Tuple` as a parent to `Unit`.
1264-
* Add the right `*:` instance as a parent to Tuple1..Tuple22
1265-
*/
1266-
def fixTupleCompleter(cls: ClassSymbol): Unit = cls.infoOrCompleter match {
1267-
case completer: LazyType =>
1268-
cls.info = new LazyType {
1269-
def syntheticParent(tparams: List[TypeSymbol]): Type =
1270-
if (tparams.isEmpty) TupleTypeRef
1271-
else (tparams :\ (UnitType: Type)) ((tparam, tail) => PairType.appliedTo(tparam.typeRef, tail))
1272-
override def complete(denot: SymDenotation)(implicit ctx: Context) = {
1273-
completer.complete(denot)
1274-
denot.info match {
1275-
case info: ClassInfo =>
1276-
denot.info = info.derivedClassInfo(
1277-
classParents = info.classParents :+ syntheticParent(cls.typeParams))
1278-
}
1279-
}
1280-
}
1281-
case _ =>
1282-
}
1283-
12841272
def init()(implicit ctx: Context) = {
12851273
this.ctx = ctx
12861274
if (!isInitialized) {
@@ -1298,10 +1286,6 @@ class Definitions {
12981286
// force initialization of every symbol that is synthesized or hijacked by the compiler
12991287
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
13001288

1301-
fixTupleCompleter(UnitClass)
1302-
for (i <- 1 to MaxTupleArity)
1303-
fixTupleCompleter(TupleType(i).symbol.asClass)
1304-
13051289
isInitialized = true
13061290
}
13071291
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ class TreeUnpickler(reader: TastyReader,
865865
case _ => readTpt()(parentCtx)
866866
}
867867
}
868-
val parentTypes = parents.map(_.tpe.dealias)
868+
val parentTypes = defn.adjustForTuple(cls, cls.typeParams, parents.map(_.tpe.dealias))
869869
val self =
870870
if (nextByte == SELFDEF) {
871871
readByte()

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ object Scala2Unpickler {
107107
else selfInfo
108108
val tempInfo = new TempClassInfo(denot.owner.thisType, cls, decls, ost)
109109
denot.info = tempInfo // first rough info to avoid CyclicReferences
110-
val normalizedParents =
111-
if (parents.isEmpty) defn.ObjectType :: Nil
112-
else parents.map(_.dealias)
110+
var normalizedParents =
111+
defn.adjustForTuple(cls, tparams,
112+
if (parents.isEmpty) defn.ObjectType :: Nil else parents.map(_.dealias))
113113
for (tparam <- tparams) {
114114
val tsym = decls.lookup(tparam.name)
115115
if (tsym.exists) tsym.setFlag(TypeParam)

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,8 @@ class Namer { typer: Typer =>
939939
index(rest)(ctx.inClassContext(selfInfo))
940940
symbolOfTree(constr).ensureCompleted()
941941

942-
val parentTypes = ensureFirstIsClass(parents.map(checkedParentType(_)), cls.pos)
942+
val parentTypes = defn.adjustForTuple(cls, cls.typeParams,
943+
ensureFirstIsClass(parents.map(checkedParentType(_)), cls.pos))
943944
typr.println(i"completing $denot, parents = $parents%, %, parentTypes = $parentTypes%, %")
944945

945946
tempInfo.finalize(denot, parentTypes)

0 commit comments

Comments
 (0)