From 8b9bdfe5f0c8c084b2db90ddcc0b5bbc25347034 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 29 Aug 2014 11:18:59 +0200 Subject: Avoid cyclic reference errors in ShowScala This is done by predicating some shortcuts on tp.symbol.isStatic where tp is a NamedType with the condition tp.denotationIsCurrent, i.e. we avoid forcing the denotation. This safe because the branches taken on isStatic are optimizations. This commit contains the minimum set of changes to make showScala pass. --- src/dotty/tools/dotc/core/Substituters.scala | 4 ++-- src/dotty/tools/dotc/core/Types.scala | 5 +++-- src/dotty/tools/dotc/printing/PlainPrinter.scala | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala index fdcc077b3..c67d352a4 100644 --- a/src/dotty/tools/dotc/core/Substituters.scala +++ b/src/dotty/tools/dotc/core/Substituters.scala @@ -12,7 +12,7 @@ trait Substituters { this: Context => case tp: BoundType => if (tp.binder eq from) tp.copyBoundType(to.asInstanceOf[tp.BT]) else tp case tp: NamedType => - if (tp.symbol.isStatic) tp + if (tp.denotationIsCurrent && tp.symbol.isStatic) tp else tp.derivedSelect(subst(tp.prefix, from, to, theMap)) case _: ThisType | NoPrefix => tp @@ -184,7 +184,7 @@ trait Substituters { this: Context => case tp @ RefinedThis(rt) => if (rt eq from) to else tp case tp: NamedType => - if (tp.symbol.isStatic) tp + if (tp.denotationIsCurrent && tp.symbol.isStatic) tp else tp.derivedSelect(substThis(tp.prefix, from, to, theMap)) case _: ThisType | _: BoundType | NoPrefix => tp diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 63a26e21a..c2d465f7f 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1102,7 +1102,8 @@ object Types { // (1) checkedPeriod != Nowhere => lastDenotation != null // (2) lastDenotation != null => lastSymbol != null - def knownDenotation: Boolean = lastDenotation != null + def denotationIsCurrent(implicit ctx: Context) = + lastDenotation != null && lastDenotation.validFor.runId == ctx.runId /** The denotation currently denoted by this type */ final def denot(implicit ctx: Context): Denotation = { @@ -2658,7 +2659,7 @@ object Types { this(x, if (tp1.exists) tp1 else tp.prefix) } case tp: TermRef => - if (stopAtStatic && tp.symbol.isStatic) x + if (stopAtStatic && tp.denotationIsCurrent && tp.symbol.isStatic) x else this(x, tp.prefix) case _: ThisType diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala index f4eb8606c..7a2b93178 100644 --- a/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -94,7 +94,7 @@ class PlainPrinter(_ctx: Context) extends Printer { tp match { case tp: TypeType => toTextRHS(tp) - case tp: TermRef if !tp.knownDenotation => + case tp: TermRef if !tp.denotationIsCurrent => toTextRef(tp) ~ ".type" case tp: TermRef if tp.denot.isOverloaded => "" @@ -182,7 +182,7 @@ class PlainPrinter(_ctx: Context) extends Printer { text.stripPrefix(objectPrefix).stripPrefix(packagePrefix) protected def selectionString(tp: NamedType) = - if (tp.knownDenotation && tp.symbol.exists) nameString(tp.symbol) + if (tp.denotationIsCurrent && tp.symbol.exists) nameString(tp.symbol) else nameString(tp.name) /** The string representation of this type used as a prefix */ -- cgit v1.2.3