From 1a3aeb147dff4875d8bf6701571babdaca9d869c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 22 Jul 2016 16:12:16 +0200 Subject: Resume suspensions also when reading from classfiles Make treatment in Scala2Unpickler and Namer the same and factor out common functionality. --- src/dotty/tools/dotc/core/TypeOps.scala | 2 +- src/dotty/tools/dotc/core/Types.scala | 12 ++++++++++-- .../tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 6 +++--- src/dotty/tools/dotc/typer/Namer.scala | 7 +++---- 4 files changed, 17 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 9433cb882..93b1b1f02 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -374,7 +374,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. if (argSym is BaseTypeArg) forwardRef(argSym, from, to, cls, decls) pref.info match { - case info: TempClassInfo => info.suspensions = (() => forward()) :: info.suspensions // !!! dotty deviation `forward` alone does not eta expand + case info: TempClassInfo => info.addSuspension(forward) case _ => forward() } } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 8019750bf..373428108 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -3049,12 +3049,20 @@ object Types { /** A class for temporary class infos where `parents` are not yet known. */ final class TempClassInfo(prefix: Type, cls: ClassSymbol, decls: Scope, selfInfo: DotClass) extends CachedClassInfo(prefix, cls, Nil, decls, selfInfo) { - + /** A list of actions that were because they rely on the class info of `cls` to * be no longer temporary. These actions will be performed once `cls` gets a real * ClassInfo. */ - var suspensions: List[() => Unit] = Nil + private var suspensions: List[() => Unit] = Nil + + def addSuspension(suspension: () => Unit): Unit = suspensions ::= suspension + + /** Install classinfo with known parents in `denot` and resume all suspensions */ + def finalize(denot: SymDenotation, parents: List[TypeRef])(implicit ctx: Context) = { + denot.info = derivedClassInfo(classParents = parents) + suspensions.foreach(_()) + } } object ClassInfo { diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 14747619a..8ea4cecde 100644 --- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -106,7 +106,8 @@ object Scala2Unpickler { // `denot.sourceModule.exists` provision i859.scala crashes in the backend. denot.owner.thisType select denot.sourceModule else selfInfo - denot.info = new TempClassInfo(denot.owner.thisType, denot.classSymbol, decls, ost) // first rough info to avoid CyclicReferences + val tempInfo = new TempClassInfo(denot.owner.thisType, denot.classSymbol, decls, ost) + denot.info = tempInfo // first rough info to avoid CyclicReferences var parentRefs = ctx.normalizeToClassRefs(parents, cls, decls) if (parentRefs.isEmpty) parentRefs = defn.ObjectType :: Nil for (tparam <- tparams) { @@ -132,8 +133,7 @@ object Scala2Unpickler { registerCompanionPair(scalacCompanion, denot.classSymbol) } - denot.info = ClassInfo( // final info, except possibly for typeparams ordering - denot.owner.thisType, denot.classSymbol, parentRefs, decls, ost) + tempInfo.finalize(denot, parentRefs) // install final info, except possibly for typeparams ordering denot.ensureTypeParamsInCorrectOrder() } } diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 20cf09846..26c8f5c95 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -688,8 +688,8 @@ class Namer { typer: Typer => else createSymbol(self) // pre-set info, so that parent types can refer to type params - val tempClassInfo = new TempClassInfo(cls.owner.thisType, cls, decls, selfInfo) - denot.info = tempClassInfo + val tempInfo = new TempClassInfo(cls.owner.thisType, cls, decls, selfInfo) + denot.info = tempInfo // Ensure constructor is completed so that any parameter accessors // which have type trees deriving from its parameters can be @@ -705,8 +705,7 @@ class Namer { typer: Typer => typr.println(s"completing $denot, parents = $parents, parentTypes = $parentTypes, parentRefs = $parentRefs") index(rest)(inClassContext(selfInfo)) - denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo) - tempClassInfo.suspensions.foreach(_()) + tempInfo.finalize(denot, parentRefs) Checking.checkWellFormed(cls) if (isDerivedValueClass(cls)) cls.setFlag(Final) -- cgit v1.2.3