diff options
author | Paul Phillips <paulp@improving.org> | 2012-08-31 10:20:16 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-08-31 16:57:19 -0700 |
commit | a3680be29ccd5314c5d027d473b37940eaecd530 (patch) | |
tree | 85c93f1ad3352d2631b08c4c84e8bc1e231ff7cb /src/compiler/scala/tools/nsc/typechecker/Duplicators.scala | |
parent | f4c45ae204ce3ff3c16b19cab266d0b6515b6e0f (diff) | |
download | scala-a3680be29ccd5314c5d027d473b37940eaecd530.tar.gz scala-a3680be29ccd5314c5d027d473b37940eaecd530.tar.bz2 scala-a3680be29ccd5314c5d027d473b37940eaecd530.zip |
Actual fix for SI-6301, specialized crasher.
This means the workaround in the previous commit is no
longer reached, but it should remain where it is as a much
needed layer of robustness/useful error reporting.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Duplicators.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Duplicators.scala | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 070f083a89..41fbaa168e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -317,13 +317,33 @@ abstract class Duplicators extends Analyzer { super.typed(tree, mode, pt) case Select(th @ This(_), sel) if (oldClassOwner ne null) && (th.symbol == oldClassOwner) => - // log("selection on this, no type ascription required") - // we use the symbol name instead of the tree name because the symbol may have been - // name mangled, rendering the tree name obsolete - // log(tree) - val t = super.typed(atPos(tree.pos)(Select(This(newClassOwner), tree.symbol.name)), mode, pt) - // log("typed to: " + t + "; tpe = " + t.tpe + "; " + inspectTpe(t.tpe)) - t + // We use the symbol name instead of the tree name because the symbol + // may have been name mangled, rendering the tree name obsolete. + // ...but you can't just do a Select on a name because if the symbol is + // overloaded, you will crash in the backend. + val memberByName = newClassOwner.thisType.member(tree.symbol.name) + def nameSelection = Select(This(newClassOwner), tree.symbol.name) + val newTree = ( + if (memberByName.isOverloaded) { + // Find the types of the overload alternatives as seen in the new class, + // and filter the list down to those which match the old type (after + // fixing the old type so it is seen as if from the new class.) + val typeInNewClass = fixType(oldClassOwner.info memberType tree.symbol) + val alts = memberByName.alternatives + val memberTypes = alts map (newClassOwner.info memberType _) + val memberString = memberByName.defString + alts zip memberTypes filter (_._2 =:= typeInNewClass) match { + case ((alt, tpe)) :: Nil => + log(s"Arrested overloaded type in Duplicators, narrowing to ${alt.defStringSeenAs(tpe)}\n Overload was: $memberString") + Select(This(newClassOwner), alt) + case _ => + log(s"Could not disambiguate $memberString in Duplicators. Attempting name-based selection, but this may not end well...") + nameSelection + } + } + else nameSelection + ) + super.typed(atPos(tree.pos)(newTree), mode, pt) case This(_) if (oldClassOwner ne null) && (tree.symbol == oldClassOwner) => // val tree1 = Typed(This(newClassOwner), TypeTree(fixType(tree.tpe.widen))) |