aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-12-17 23:09:22 +0100
committerMartin Odersky <odersky@gmail.com>2013-12-17 23:27:43 +0100
commit9e8d0709e9f43fbb1dc40baaab4f0891538d8e9c (patch)
tree2aaa37431319ba479fe406a507349511735d2ac9
parent9a839d706291fdd57aeb48c3f64654afbd144a83 (diff)
downloaddotty-9e8d0709e9f43fbb1dc40baaab4f0891538d8e9c.tar.gz
dotty-9e8d0709e9f43fbb1dc40baaab4f0891538d8e9c.tar.bz2
dotty-9e8d0709e9f43fbb1dc40baaab4f0891538d8e9c.zip
Special handling of implicit members.
The previous treatment would force all members, causing cyclic reference errors. We fix it by filtering early in computeMemberNames itself for implicits.
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala7
-rw-r--r--src/dotty/tools/dotc/core/Types.scala7
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--tests/pos/overloaded.scala10
4 files changed, 21 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 0fd8f1acb..a3ce8af6e 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -1040,11 +1040,14 @@ object SymDenotations {
def memberNames(keepOnly: NameFilter)(implicit ctx: Context): Set[Name] = {
def computeMemberNames: Set[Name] = {
val inheritedNames = (classParents flatMap (_.memberNames(keepOnly, thisType))).toSet
- val ownNames = info.decls.iterator map (_.name)
+ var ownSyms = info.decls.toList
+ if (keepOnly == implicitFilter) ownSyms = ownSyms filter (_ is Implicit)
+ val ownNames = ownSyms.iterator map (_.name)
val candidates = inheritedNames ++ ownNames
candidates filter (keepOnly(thisType, _))
}
- if ((this is PackageClass) || !Config.cacheMemberNames) computeMemberNames // don't cache package member names; they might change
+ if ((this is PackageClass) || (keepOnly == implicitFilter) || !Config.cacheMemberNames)
+ computeMemberNames // don't cache package member names; they might change
else {
val cached = memberNamesCache(keepOnly)
if (cached != null) cached
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 5976cf93b..c0e4ccb14 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2297,8 +2297,11 @@ object Types {
}
object implicitFilter extends NameFilter {
- def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean =
- (pre member name).hasAltWith(_.symbol is Implicit)
+ /** A dummy filter method.
+ * Implicit filtering is handled specially in computeMemberNames, so
+ * no post-filtering is needed.
+ */
+ def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = true
}
// ----- Exceptions -------------------------------------------------------------
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 31fe8051e..72167c53e 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -30,6 +30,7 @@ class tests extends CompilerTest {
@Test def pos_typedidents() = compileFile(posDir, "typedidents")
@Test def pos_assignments() = compileFile(posDir, "assignments")
@Test def pos_packageobject() = compileFile(posDir, "packageobject")
+ @Test def pos_overloaded() = compileFile(posDir, "overloaded")
@Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 2)
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
diff --git a/tests/pos/overloaded.scala b/tests/pos/overloaded.scala
new file mode 100644
index 000000000..d76585f93
--- /dev/null
+++ b/tests/pos/overloaded.scala
@@ -0,0 +1,10 @@
+object overloaded {
+
+ def f(x: String): String = x
+ def f[T >: Null](x: T): Int = 1
+
+ val x1 = f("abc")
+ val x2 = f(new Integer(1))
+ val x3 = f(null)
+
+}