From 9c834fc8887c419ff617edb3811e3a3fa611932f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 26 Jan 2018 13:33:06 +0100 Subject: [PATCH 1/2] Fix #1771: Harden namer in the presence of double definitions i1771.scala exhibits a case where an inner class is a double definition of a type parameter. The inner class then gets renamed, but this caused problems for the generation of companion links. Companion links are fixed in Namer. There is also a change in Typer, where a missing OriginalSymbol caused a crash. It turned out this was caused by the companion link generation so once the latter was fixed, the crash did not happen anymore. Nevertheless I feel it's more prudent to turn the crash into a "this should not happen" error, because we might have overlooked other error paths that also lead to missing OriginalSymbols. --- .../src/dotty/tools/dotc/typer/Namer.scala | 6 ++++-- .../src/dotty/tools/dotc/typer/Typer.scala | 21 +++++++++---------- tests/pos/i1771.scala | 4 ++++ 3 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 tests/pos/i1771.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index e770d2c615f3..867fd1d0ebae 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -590,8 +590,10 @@ class Namer { typer: Typer => def createLinks(classTree: TypeDef, moduleTree: TypeDef)(implicit ctx: Context) = { val claz = ctx.effectiveScope.lookup(classTree.name) val modl = ctx.effectiveScope.lookup(moduleTree.name) - ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD, claz, modl).entered - ctx.synthesizeCompanionMethod(nme.COMPANION_MODULE_METHOD, modl, claz).entered + if (claz.isClass && modl.isClass) { + ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD, claz, modl).entered + ctx.synthesizeCompanionMethod(nme.COMPANION_MODULE_METHOD, modl, claz).entered + } } def createCompanionLinks(implicit ctx: Context): Unit = { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 5c722a1c92c6..5f023820bc07 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1141,20 +1141,19 @@ class Typer extends Namer bindings1, expansion1) } - def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") { + def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): Tree = track("typedTypeTree") { tree match { case tree: untpd.DerivedTypeTree => tree.ensureCompletions - try - TypeTree(tree.derivedType(tree.attachment(untpd.OriginalSymbol))) withPos tree.pos - // btw, no need to remove the attachment. The typed - // tree is different from the untyped one, so the - // untyped tree is no longer accessed after all - // accesses with typedTypeTree are done. - catch { - case ex: NoSuchElementException => - println(s"missing OriginalSymbol for ${ctx.owner.ownersIterator.toList}") - throw ex + tree.getAttachment(untpd.OriginalSymbol) match { + case Some(origSym) => + TypeTree(tree.derivedType(origSym)).withPos(tree.pos) + // btw, no need to remove the attachment. The typed + // tree is different from the untyped one, so the + // untyped tree is no longer accessed after all + // accesses with typedTypeTree are done. + case None => + errorTree(tree, "Something's wrong: missing original symbol for type tree") } case _ => tree.withType( diff --git a/tests/pos/i1771.scala b/tests/pos/i1771.scala new file mode 100644 index 000000000000..6a96ad35da36 --- /dev/null +++ b/tests/pos/i1771.scala @@ -0,0 +1,4 @@ +class GBTree[B] { + class Tree[A, B]; class Node[A, B](value: Node[A, B]) extends Tree[A, B] + case class B[A, B]() extends Tree[A, B] +} From 74a9e1091bf0056025cb802a56c09a902308d90c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 26 Jan 2018 13:56:35 +0100 Subject: [PATCH 2/2] Move test to neg --- tests/{pos => neg}/i1771.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{pos => neg}/i1771.scala (57%) diff --git a/tests/pos/i1771.scala b/tests/neg/i1771.scala similarity index 57% rename from tests/pos/i1771.scala rename to tests/neg/i1771.scala index 6a96ad35da36..6b96ba3af044 100644 --- a/tests/pos/i1771.scala +++ b/tests/neg/i1771.scala @@ -1,4 +1,4 @@ class GBTree[B] { class Tree[A, B]; class Node[A, B](value: Node[A, B]) extends Tree[A, B] - case class B[A, B]() extends Tree[A, B] + case class B[A, B]() extends Tree[A, B] // error: double definition }