Skip to content

Commit 949c48e

Browse files
committed
Get more info on Heisenbugs
1) Check that searched scope is consistent 2) Do a linear search for symbol with name, and report if something was found that way.
1 parent b112b2b commit 949c48e

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

src/dotty/tools/dotc/core/Scopes.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ object Scopes {
142142
def openForMutations: MutableScope = unsupported("openForMutations")
143143

144144
final def toText(printer: Printer): Text = printer.toText(this)
145+
146+
def checkConsistent()(implicit ctx: Context) = ()
145147
}
146148

147149
/** A subclass of Scope that defines methods for entering and
@@ -240,6 +242,7 @@ object Scopes {
240242
else {
241243
hashTable = new Array[ScopeEntry](tableSize)
242244
enterAllInHash(lastEntry)
245+
// checkConsistent() // DEBUG
243246
}
244247

245248
private def enterAllInHash(e: ScopeEntry, n: Int = 0)(implicit ctx: Context): Unit = {
@@ -378,6 +381,17 @@ object Scopes {
378381
}
379382

380383
override def openForMutations: MutableScope = this
384+
385+
/** Check that all symbols in this scope are in their correct hashtable buckets. */
386+
override def checkConsistent()(implicit ctx: Context) = {
387+
var e = lastEntry
388+
while (e != null) {
389+
var e1 = lookupEntry(e.name)
390+
while (e1 != e && e1 != null) e1 = lookupNextEntry(e1)
391+
assert(e1 == e, s"PANIC: Entry ${e.name} is badly linked")
392+
e = e.prev
393+
}
394+
}
381395
}
382396

383397
/** Create a new scope */

src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
383383
if (sym.exists || owner.ne(defn.ObjectClass)) sym else declIn(defn.AnyClass)
384384
}
385385

386+
def slowSearch(name: Name): Symbol =
387+
owner.info.decls.find(_.name == name).getOrElse(NoSymbol)
388+
386389
def nestedObjectSymbol: Symbol = {
387390
// If the owner is overloaded (i.e. a method), it's not possible to select the
388391
// right member, so return NoSymbol. This can only happen when unpickling a tree.
@@ -414,13 +417,16 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
414417
fromName(name.toTermName.expandedName(owner)) orElse {
415418
// (3) Try as a nested object symbol.
416419
nestedObjectSymbol orElse {
417-
// // (4) Call the mirror's "missing" hook.
420+
// (4) Call the mirror's "missing" hook.
418421
adjust(ctx.base.missingHook(owner, name)) orElse {
419422
// println(owner.info.decls.toList.map(_.debugString).mkString("\n ")) // !!! DEBUG
420423
// }
421424
// (5) Create a stub symbol to defer hard failure a little longer.
422425
System.err.println(i"***** missing reference, looking for $name in $owner")
423426
System.err.println(i"decls = ${owner.info.decls}")
427+
owner.info.decls.checkConsistent()
428+
if (slowSearch(name).exists)
429+
System.err.println(i"**** slow search found: ${slowSearch(name)}")
424430
new Exception().printStackTrace()
425431
ctx.newStubSymbol(owner, name, source)
426432
}

0 commit comments

Comments
 (0)