aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-04-10 10:09:06 +0200
committerMartin Odersky <odersky@gmail.com>2013-04-10 10:09:06 +0200
commit1034d4e420c2b0724945486f341c53a07e6a90e0 (patch)
tree0d06fb6ab5591e8c56053c737184130bacf2641d /src/dotty
parentac8b319ed4738b2200350adb3943eb558157e1b7 (diff)
downloaddotty-1034d4e420c2b0724945486f341c53a07e6a90e0.tar.gz
dotty-1034d4e420c2b0724945486f341c53a07e6a90e0.tar.bz2
dotty-1034d4e420c2b0724945486f341c53a07e6a90e0.zip
Removing automatic legal prefix checking.
It turned out this led to cycles in subtyping. We need to check for legal prefixes only for types that are declared or inferred in source. For the rest, we should assume that the type is OK.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala35
-rw-r--r--src/dotty/tools/dotc/core/Printers.scala4
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala1
-rw-r--r--src/dotty/tools/dotc/core/Types.scala17
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala2
5 files changed, 40 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 092330ac9..29da40caf 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -128,17 +128,32 @@ object Contexts {
protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
def diagnostics: Option[StringBuilder] = _diagnostics
- /** Should prefix of type selections to be checked whether it's stable?
- * Disabled when reading Scala pickled information.
- */
- private var _checkPrefix: Boolean = true
- protected def checkPrefix_=(checkPrefix: Boolean) = _checkPrefix = checkPrefix
- def checkPrefix: Boolean = _checkPrefix
-
+ /** A map in which more contextual properties can be stored */
private var _moreProperties: Map[String, Any] = _
protected def moreProperties_=(moreProperties: Map[String, Any]) = _moreProperties = moreProperties
def moreProperties: Map[String, Any] = _moreProperties
+ /** If -Ydebug is on, the top of the stack trace where this context
+ * was created, otherwise `null`.
+ */
+ private var creationTrace: Array[StackTraceElement] = _
+
+ setCreationTrace()
+
+ private def setCreationTrace() =
+ if (true || this.settings.debug.value)
+ creationTrace = (new Throwable).getStackTrace().take(20)
+
+ /** Print all enclosing context's creation stacktraces */
+ def printCreationTraces() = {
+ println("=== context creation trace =======")
+ for (ctx <- outersIterator) {
+ println(s">>>>>>>>> $ctx")
+ if (ctx.creationTrace != null) println(ctx.creationTrace.mkString("\n"))
+ }
+ println("=== end context creation trace ===")
+ }
+
/** Leave message in diagnostics buffer if it exists */
def diagnose(str: => String) =
for (sb <- diagnostics) {
@@ -192,6 +207,7 @@ object Contexts {
def fresh: FreshContext = {
val newctx = super.clone.asInstanceOf[FreshContext]
newctx.outer = this
+ newctx.setCreationTrace()
newctx
}
}
@@ -218,9 +234,8 @@ object Contexts {
def withTree(tree: Tree): this.type = { this.tree = tree; this }
def withReporter(reporter: Reporter): this.type = { this.reporter = reporter; this }
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
- def withCheckPrefix(checkPrefix: Boolean): this.type = { this.checkPrefix = checkPrefix; this }
def withMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this }
-
+
def withProperty(prop: (String, Any)): this.type = withMoreProperties(moreProperties + prop)
def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid))
@@ -229,7 +244,6 @@ object Contexts {
withSettings(setting.updateIn(sstate, value))
def withDebug = withSetting(base.settings.debug, true)
-
}
/** A class defining the initial context with given context base
@@ -365,7 +379,6 @@ object Contexts {
val theBase = new ContextBase // !!! DEBUG, so that we can use a minimal context for reporting even in code that normallly cannot access a context
}
-
/** Initial size of superId table */
private final val InitialSuperIdsSize = 4096
diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala
index fe69c65e6..6255a79da 100644
--- a/src/dotty/tools/dotc/core/Printers.scala
+++ b/src/dotty/tools/dotc/core/Printers.scala
@@ -89,7 +89,7 @@ object Printers {
}
class PlainPrinter(_ctx: Context) extends Printer {
- protected[this] implicit val ctx = _ctx.fresh.withCheckPrefix(false)
+ protected[this] implicit val ctx = _ctx
def controlled(op: => Text): Text =
if (ctx.toTextRecursions < maxToTextRecursions)
@@ -499,7 +499,7 @@ object Printers {
override protected def treatAsTypeArg(sym: Symbol) =
sym.isType && (sym is ProtectedLocal) &&
- (ctx.traceIndented(s"$sym.allOverriddenSymbols")(sym.allOverriddenSymbols) exists (_ is TypeParam))
+ (sym.allOverriddenSymbols exists (_ is TypeParam))
override protected def reconstituteParent(cls: ClassSymbol, parent: Type): Type =
(parent /: parent.classSymbol.typeParams) { (parent, tparam) =>
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 0b8f494d0..a559e9d79 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -766,7 +766,6 @@ object SymDenotations {
* gets invalidated.
*/
def memberFingerPrint(implicit ctx: Context): FingerPrint = {
- assert(classSymbol.hasChildren)
if (_memberFingerPrint == FingerPrint.empty) _memberFingerPrint = computeMemberFingerPrint
_memberFingerPrint
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 22ea23b52..7656835cf 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -901,10 +901,15 @@ object Types {
lastDenotation.current
} else {
val d = loadDenot
+/* need to do elsewhere as it leads to a cycle in subtyping here.
if (d.exists && !d.symbol.isAliasType && !prefix.isLegalPrefix) {
- val ex = new MalformedType(prefix, d)
- if (ctx.checkPrefix) throw ex else ctx.log(ex.getMessage)
+ val ex = new MalformedType(prefix, d, prefix.memberNames(abstractTypeNameFilter))
+ if (ctx.checkPrefix) {
+ ctx.printCreationTrace()
+ throw ex
+ } else ctx.log(ex.getMessage)
}
+*/
if (d.exists || ctx.phaseId == FirstPhaseId)
d
else // name has changed; try load in earlier phase and make current
@@ -1710,8 +1715,12 @@ object Types {
class TypeError(msg: String) extends Exception(msg)
class FatalTypeError(msg: String) extends TypeError(msg)
- class MalformedType(pre: Type, denot: Denotation)
- extends FatalTypeError(s"malformed type: $pre is not a legal prefix for $denot")
+
+ class MalformedType(pre: Type, denot: Denotation, absMembers: Set[Name])
+ extends FatalTypeError(
+ s"""malformed type: $pre is not a legal prefix for $denot because it contains abstract type member${if (absMembers.size == 1) "" else "s"} ${absMembers.mkString(", ")}"""
+ .stripMargin)
+
class CyclicReference(val denot: SymDenotation)
extends FatalTypeError(s"cyclic reference involving $denot")
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index e17588e60..801841915 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -18,7 +18,7 @@ class ClassfileParser(
classRoot: ClassDenotation,
moduleRoot: ClassDenotation)(cctx0: CondensedContext) {
- implicit val cctx: CondensedContext = cctx0.fresh.withCheckPrefix(false)
+ implicit val cctx: CondensedContext = cctx0
import ClassfileConstants._
import cctx.base.{settings, loaders, definitions => defn}