diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-06 09:46:07 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-03-07 11:12:33 +0100 |
commit | 5b30038dd3561468a8f4a9a9f50e1a0208062de1 (patch) | |
tree | 70433caeada230d4e87c13b91f7644a0bbb910ba /src/dotty/tools/dotc | |
parent | ccb4f8afb7af71364c1b3d0f6565d686155a8e66 (diff) | |
download | dotty-5b30038dd3561468a8f4a9a9f50e1a0208062de1.tar.gz dotty-5b30038dd3561468a8f4a9a9f50e1a0208062de1.tar.bz2 dotty-5b30038dd3561468a8f4a9a9f50e1a0208062de1.zip |
Fix problem comparing overloaded TermRefs
Overloaded TermRefs do not have an info, and consequently do not support =:=. Yet in Typer#checkNewOrShadowed we compared termrefs with =:=. This gives an exception if the termrefs are overloaded. The fix is to provide a new method isSameRef in TypeComparer which is called instead of =:= in Typer#checkNewOrShadowed.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 22 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 2 |
2 files changed, 20 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index d46a8387f..ffb20cbad 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -715,9 +715,25 @@ class TypeComparer(initctx: Context) extends DotClass { /** Two types are the same if are mutual subtypes of each other */ def isSameType(tp1: Type, tp2: Type): Boolean = - if (tp1 == NoType || tp2 == NoType) false - else if (tp1 eq tp2) true - else isSubType(tp1, tp2) && isSubType(tp2, tp1) + isSubType(tp1, tp2) && isSubType(tp2, tp1) + + /** Same as `isSameType` but also can be applied to overloaded TermRefs, where + * two overloaded refs are the same if they have pairwise equal alternatives + */ + def isSameRef(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSameRef($tp1, $tp2") { + def isSubRef(tp1: Type, tp2: Type): Boolean = tp1 match { + case tp1: TermRef if tp1.isOverloaded => + tp1.alternatives forall (isSubRef(_, tp2)) + case _ => + tp2 match { + case tp2: TermRef if tp2.isOverloaded => + tp2.alternatives exists (isSubRef(tp1, _)) + case _ => + isSubType(tp1, tp2) + } + } + isSubRef(tp1, tp2) && isSubRef(tp2, tp1) + } /** The greatest lower bound of two types */ def glb(tp1: Type, tp2: Type): Type = /*>|>*/ ctx.traceIndented(s"glb(${tp1.show}, ${tp2.show})", typr, show = true) /*<|<*/ { diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index e6f566193..aabcde94d 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -244,7 +244,7 @@ class Typer extends Namer with Applications with Implicits { * does properly shadow the new one from an outer context. */ def checkNewOrShadowed(found: Type, newPrec: Int): Type = - if (!previous.exists || (previous =:= found)) found + if (!previous.exists || ctx.typeComparer.isSameRef(previous, found)) found else if ((prevCtx.scope eq ctx.scope) && (newPrec == definition || newPrec == namedImport && prevPrec == wildImport)) { |