summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-07-21 07:11:30 -0700
committerPaul Phillips <paulp@improving.org>2012-07-21 10:52:31 -0700
commit9fecdfd8cb03816f7992c1577e296854c4dc878b (patch)
treed8ede036d0e353edc3159188e6cf8bcdfeaa7c7a /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent729aad67224e987849114770b63f81897845f15a (diff)
downloadscala-9fecdfd8cb03816f7992c1577e296854c4dc878b.tar.gz
scala-9fecdfd8cb03816f7992c1577e296854c4dc878b.tar.bz2
scala-9fecdfd8cb03816f7992c1577e296854c4dc878b.zip
Fix SI-6117, regression involving import ambiguity.
Today I learned that foo.member("bar") != foo.member("bar") if bar is overloaded, because each lookup of an overloaded member creates a new symbol (with equivalent OverloadedTypes.) How should symbols be compared so these do not appear unequal? Is there a method which unpacks the alternatives and compares them individually? It seems likely there are additional bugs which arise from not covering this case. Since this bug is in the context of importing, if the prefixes are identical then I can compare the names instead of the symbols and this issue goes away. But for the rest of the time during which one might encounter overloaded symbols, that would be a very lossy operation, since the overloaded symbol might be encoding any subset of the members with that name. There are lots of references to "OverloadedSymbol" in the comments of various methods in Types, but no such class is visible in the history. If we had such a thing, we could refine its equals method to recognize equivalent overloads. Review by @odersky.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index dbe65c16d8..bc02df23d7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4652,15 +4652,28 @@ trait Typers extends Modes with Adaptations with Tags {
// If the ambiguous name is a monomorphic type, we can relax this far.
def mt1 = t1 memberType impSym
def mt2 = t2 memberType impSym1
+ def characterize = List(
+ s"types: $t1 =:= $t2 ${t1 =:= t2} members: ${mt1 =:= mt2}",
+ s"member type 1: $mt1",
+ s"member type 2: $mt2",
+ s"$impSym == $impSym1 ${impSym == impSym1}",
+ s"${impSym.debugLocationString} ${impSym.getClass}",
+ s"${impSym1.debugLocationString} ${impSym1.getClass}"
+ ).mkString("\n ")
+
+ // The symbol names are checked rather than the symbols themselves because
+ // each time an overloaded member is looked up it receives a new symbol.
+ // So foo.member("x") != foo.member("x") if x is overloaded. This seems
+ // likely to be the cause of other bugs too...
+ if (t1 =:= t2 && impSym.name == impSym1.name)
+ log(s"Suppressing ambiguous import: $t1 =:= $t2 && $impSym == $impSym1")
// Monomorphism restriction on types is in part because type aliases could have the
// same target type but attach different variance to the parameters. Maybe it can be
// relaxed, but doesn't seem worth it at present.
- if (t1 =:= t2 && impSym == impSym1)
- log(s"Suppressing ambiguous import: $t1 =:= $t2 && $impSym == $impSym1")
else if (mt1 =:= mt2 && name.isTypeName && impSym.isMonomorphicType && impSym1.isMonomorphicType)
log(s"Suppressing ambiguous import: $mt1 =:= $mt2 && $impSym and $impSym1 are equivalent")
else {
- log(s"Import is genuinely ambiguous: !($t1 =:= $t2)")
+ log(s"Import is genuinely ambiguous:\n " + characterize)
ambiguousError(s"it is imported twice in the same scope by\n${imports.head}\nand ${imports1.head}")
}
}