From 43f2cc5832c2d66fd337cf8d362e3e4907e0e952 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 4 Aug 2017 11:46:49 +0200 Subject: [PATCH] Fix #2943: Insert LazyRefs automatically upon Unpickling This relieves Tasty producers from having to insert LazyRefs themselves. Fixes #2943. --- .../src/dotty/tools/dotc/core/tasty/TastyFormat.scala | 3 --- .../src/dotty/tools/dotc/core/tasty/TreePickler.scala | 1 - .../src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 8 +++----- compiler/src/dotty/tools/dotc/typer/Checking.scala | 3 ++- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index 3b04d6d67eb7..df8caa1b8653 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -164,7 +164,6 @@ Standard-Section: "ASTs" TopLevelStat* BIND Length boundName_NameRef bounds_Type // for type-variables defined in a type pattern BYNAMEtype underlying_Type - LAZYref underlying_Type POLYtype Length result_Type NamesTypes METHODtype Length result_Type NamesTypes // needed for refinements TYPELAMBDAtype Length result_Type NamesTypes // variance encoded in front of name: +/-/(nothing) @@ -323,7 +322,6 @@ object TastyFormat { final val PROTECTEDqualified = 105 final val RECtype = 106 final val SINGLETONtpt = 107 - final val LAZYref = 108 final val IDENT = 112 final val IDENTtpt = 113 @@ -514,7 +512,6 @@ object TastyFormat { case DOUBLEconst => "DOUBLEconst" case STRINGconst => "STRINGconst" case RECtype => "RECtype" - case LAZYref => "LAZYref" case IDENT => "IDENT" case IDENTtpt => "IDENTtpt" diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 885a76e3f763..338a395ab685 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -246,7 +246,6 @@ class TreePickler(pickler: TastyPickler) { case tpe: ParamRef => assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe") case tpe: LazyRef => - writeByte(LAZYref) pickleType(tpe.ref) } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 3015bef6d8e7..bf3b593b9a94 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -6,6 +6,7 @@ package tasty import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._ import StdNames._, Denotations._, Flags._, Constants._, Annotations._ import NameKinds._ +import typer.Checking.checkNonCyclic import util.Positions._ import ast.{tpd, Trees, untpd} import Trees._ @@ -293,10 +294,6 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi RecType(rt => registeringType(rt, readType())) case RECthis => RecThis(readTypeRef().asInstanceOf[RecType]) - case LAZYref => - val rdr = fork - skipTree() - LazyRef(implicit ctx => rdr.readType()) case SHARED => val ref = readAddr() typeAtAddr.getOrElseUpdate(ref, forkAt(ref).readType()) @@ -678,8 +675,9 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi TypeDef(readTemplate(localCtx)) } else { val rhs = readTpt() + sym.info = NoCompleter sym.info = rhs.tpe match { - case _: TypeBounds | _: ClassInfo => rhs.tpe + case _: TypeBounds | _: ClassInfo => checkNonCyclic(sym, rhs.tpe, reportErrors = false) case _ => TypeAlias(rhs.tpe, sym.variance) } TypeDef(rhs) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 130eb8d36754..5a3ea77638be 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -239,7 +239,8 @@ object Checking { } if (isInteresting(pre)) { val pre1 = this(pre, false, false) - if (locked.contains(tp)) throw CyclicReference(tp.symbol) + if (locked.contains(tp) || tp.symbol.infoOrCompleter == NoCompleter) + throw CyclicReference(tp.symbol) locked += tp try checkInfo(tp.info) finally locked -= tp