diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index bfaa12729090..15c943b29640 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1056,7 +1056,10 @@ object SymDenotations { else overriddenFromType(owner.asClass.classInfo.selfType) private def overriddenFromType(tp: Type)(implicit ctx: Context): Iterator[Symbol] = - tp.baseClasses.tail.iterator map overriddenSymbol filter (_.exists) + tp.baseClasses match { + case _ :: inherited => inherited.iterator map overriddenSymbol filter (_.exists) + case Nil => Iterator.empty + } /** The symbol overriding this symbol in given subclass `ofclazz`. * diff --git a/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala b/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala index 8bfc6fef3eb3..a27db1d5d5db 100644 --- a/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala +++ b/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala @@ -179,6 +179,21 @@ class InteractiveDriver(settings: List[String]) extends Driver { private val compiler: Compiler = new InteractiveCompiler + /** Remove attachments and error out completers. The goal is to avoid + * having a completer hanging in a typed tree which can capture the context + * of a previous run. Note that typed trees can have untyped or partially + * typed children if the source contains errors. + */ + private def cleanup(tree: tpd.Tree)(implicit ctx: Context): Unit = tree.foreachSubTree { t => + if (t.hasType) { + if (t.symbol.exists) { + if (!t.symbol.isCompleted) t.symbol.info = UnspecifiedErrorType + t.symbol.annotations.foreach(annot => cleanup(annot.tree)) + } + } + t.removeAllAttachments() + } + def run(uri: URI, sourceCode: String): List[MessageContainer] = { val previousCtx = myCtx try { @@ -200,6 +215,7 @@ class InteractiveDriver(settings: List[String]) extends Driver { run.compileSources(List(source)) run.printSummary() val t = run.units.head.tpdTree + cleanup(t) myOpenedTrees(uri) = topLevelClassTrees(t, source) reporter.removeBufferedMessages diff --git a/compiler/src/dotty/tools/dotc/util/Attachment.scala b/compiler/src/dotty/tools/dotc/util/Attachment.scala index 20facfd97544..ed71aba1c90b 100644 --- a/compiler/src/dotty/tools/dotc/util/Attachment.scala +++ b/compiler/src/dotty/tools/dotc/util/Attachment.scala @@ -92,5 +92,8 @@ object Attachment { assert(!getAttachment(key).isDefined, s"duplicate attachment for key $key") next = new Link(key, value, next) } + + final def removeAllAttachments() = + next = null } }