aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/SymDenotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-04-02 17:20:51 +0200
committerMartin Odersky <odersky@gmail.com>2015-04-07 23:43:15 +0200
commit553e89bf5979c7ed5436aa9581fbc3c0f46fdc5c (patch)
treeae1dee3ece8926dfeddf9272c558e33e0668c034 /src/dotty/tools/dotc/core/SymDenotations.scala
parente1e0e9abb6c2b6285d598e260cc1d1c4ac2d3c2a (diff)
downloaddotty-553e89bf5979c7ed5436aa9581fbc3c0f46fdc5c.tar.gz
dotty-553e89bf5979c7ed5436aa9581fbc3c0f46fdc5c.tar.bz2
dotty-553e89bf5979c7ed5436aa9581fbc3c0f46fdc5c.zip
Use invalidateInheritedSymbols instead of syncWithParents
syncWithParents explores the denotations of symbols that might yet to be entered in the current run. If such a symbol is looked at in a new run before a new one is entered, the validty period of the old denotation is extended to the new run and consequently references to that symbol do not know they need to reload. This pollutes the cache of references and causes StaleSymbol errors down the line. Replacing with invalidateInheritedSymbols avoids the problem.
Diffstat (limited to 'src/dotty/tools/dotc/core/SymDenotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 1285d3fdd..990c6e317 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -70,6 +70,14 @@ object SymDenotations {
override def hasUniqueSym: Boolean = exists
+ /** Debug only
+ override def validFor_=(p: Period) = {
+ if (name == "Trees".toTermName && p.runId == 3)
+ assert(symbol.id != 6161)
+ super.validFor_=(p)
+ }
+ */
+
// ------ Getting and setting fields -----------------------------
private[this] var myFlags: FlagSet = adaptFlags(initFlags)
@@ -171,13 +179,13 @@ object SymDenotations {
myInfo = tp
}
- /** The name, except
- * - if this is a module class, strip the module class suffix
- * - if this is a companion object with a clash-avoiding name, strip the
+ /** The name, except
+ * - if this is a module class, strip the module class suffix
+ * - if this is a companion object with a clash-avoiding name, strip the
* "avoid clash" suffix
*/
def effectiveName(implicit ctx: Context) =
- if (this is ModuleClass) name.stripModuleClassSuffix
+ if (this is ModuleClass) name.stripModuleClassSuffix
else name.stripAvoidClashSuffix
/** The privateWithin boundary, NoSymbol if no boundary is given.
@@ -195,7 +203,7 @@ object SymDenotations {
/** Update the annotations of this denotation */
private[core] final def annotations_=(annots: List[Annotation]): Unit =
- myAnnotations = annots
+ myAnnotations = annots
/** Does this denotation have an annotation matching the given class symbol? */
final def hasAnnotation(cls: Symbol)(implicit ctx: Context) =
@@ -241,9 +249,9 @@ object SymDenotations {
/** The symbols defined in this class or object.
* Careful! This does not force the type, so is compilation order dependent.
* This method should be used only in the following circumstances:
- *
- * 1. When accessing type parameters or type parameter accessors (both are entered before
- * completion).
+ *
+ * 1. When accessing type parameters or type parameter accessors (both are entered before
+ * completion).
* 2. When obtaining the current scope in order to enter, rename or delete something there.
* 3. When playing it safe in order not to raise CylicReferences, e.g. for printing things
* or taking more efficient shortcuts (e.g. the stillValid test).
@@ -292,7 +300,6 @@ object SymDenotations {
if (isType) fn.toTypeName else fn.toTermName
}
-
/** The encoded flat name of this denotation, where joined names are separated by `separator` characters. */
def flatName(separator: Char = '$')(implicit ctx: Context): Name =
if (symbol == NoSymbol || owner == NoSymbol || owner.isEffectiveRoot || (owner is PackageClass)) name
@@ -457,7 +464,7 @@ object SymDenotations {
}
/** Is this a user defined "def" method? Excluded are accessors and anonymous functions. */
- final def isSourceMethod(implicit ctx: Context) =
+ final def isSourceMethod(implicit ctx: Context) =
this.is(Method, butNot = AccessorOrLabel) && !isAnonymousFunction
/** Is this a setter? */
@@ -649,7 +656,7 @@ object SymDenotations {
*/
/** The class implementing this module, NoSymbol if not applicable. */
final def moduleClass(implicit ctx: Context): Symbol = {
- def notFound = {println(s"missing module class for $name: $myInfo"); NoSymbol}
+ def notFound = { println(s"missing module class for $name: $myInfo"); NoSymbol }
if (this is ModuleVal)
myInfo match {
case info: TypeRef => info.symbol
@@ -1002,7 +1009,7 @@ object SymDenotations {
s"$kindString $name"
}
- def debugString = toString+"#"+symbol.id // !!! DEBUG
+ def debugString = toString + "#" + symbol.id // !!! DEBUG
// ----- copies and transforms ----------------------------------------
@@ -1097,8 +1104,8 @@ object SymDenotations {
private var firstRunId: RunId = initRunId
- /** If caches influenced by parent classes are still valid, the denotation
- * itself, otherwise a freshly initialized copy.
+ /** invalidate caches influenced by parent classes if one of the parents
+ * is younger than the denotation itself.
*/
override def syncWithParents(implicit ctx: Context): SingleDenotation = {
def isYounger(tref: TypeRef) = tref.symbol.denot match {
@@ -1124,7 +1131,7 @@ object SymDenotations {
}
/** Invalidate all caches and fields that depend on base classes and their contents */
- private def invalidateInheritedInfo(): Unit = {
+ override def invalidateInheritedInfo(): Unit = {
myBaseClasses = null
mySuperClassBits = null
myMemberFingerPrint = FingerPrint.unknown
@@ -1168,7 +1175,7 @@ object SymDenotations {
private[this] var myBaseClasses: List[ClassSymbol] = null
private[this] var mySuperClassBits: BitSet = null
- /** Invalidate baseTypeRefCache, baseClasses and superClassBits on new run */
+ /** Invalidate baseTypeRefCache, baseClasses and superClassBits on new run */
private def checkBasesUpToDate()(implicit ctx: Context) =
if (baseTypeRefValid != ctx.runId) {
baseTypeRefCache = new java.util.HashMap[CachedType, Type]