Skip to content

Commit

Permalink
Fix #1771: Harden namer in the presence of double definitions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
odersky committed Jan 26, 2018
1 parent 5b1b747 commit 9c834fc
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
6 changes: 4 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
21 changes: 10 additions & 11 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 4 additions & 0 deletions tests/pos/i1771.scala
Original file line number Diff line number Diff line change
@@ -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]
}

0 comments on commit 9c834fc

Please sign in to comment.