summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala18
-rw-r--r--test/files/pos/t3999/a_1.scala9
-rw-r--r--test/files/pos/t3999/b_2.scala7
3 files changed, 29 insertions, 5 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index d969cb43bb..e34189657e 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -454,9 +454,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
// A package object or its module class
- final def isPackageObjectOrClass = name == nme.PACKAGE || name == tpnme.PACKAGE
- final def isPackageObject = name == nme.PACKAGE && owner.isPackageClass
- final def isPackageObjectClass = name == tpnme.PACKAGE && owner.isPackageClass
+ final def isPackageObjectOrClass = (this ne NoSymbol) && owner.isPackageClass && (name == nme.PACKAGE || name == tpnme.PACKAGE)
+ final def isPackageObject = (this ne NoSymbol) && owner.isPackageClass && name == nme.PACKAGE
+ final def isPackageObjectClass = (this ne NoSymbol) && owner.isPackageClass && name == tpnme.PACKAGE
final def isDefinedInPackage = effectiveOwner.isPackageClass
final def isJavaInterface = isJavaDefined && isTrait
@@ -467,7 +467,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The owner, skipping package objects.
*/
- def effectiveOwner = owner.skipPackageObject
+ def effectiveOwner = if (owner.isPackageObjectClass) owner.skipPackageObject else owner
/** If this is a package object or its implementing class, its owner: otherwise this.
*/
@@ -2432,7 +2432,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) {
implicitMembersCacheKey1 = tp
implicitMembersCacheKey2 = tp.decls.elems
- implicitMembersCacheValue = tp.implicitMembers
+ // When a package object which defines an implicit, it may turn up here in two
+ // forms which are not recognized as the same implicit definition, creating a
+ // spurious ambiguity (see pos/t3999). Since I haven't figured out package objects
+ // well enough to fix this at the root, I am filtering here by applying the
+ // property that a member's owner must be unique.
+ if (isPackageClass)
+ implicitMembersCacheValue = tp.implicitMembers filter (_.owner eq this)
+ else
+ implicitMembersCacheValue = tp.implicitMembers
}
implicitMembersCacheValue
}
diff --git a/test/files/pos/t3999/a_1.scala b/test/files/pos/t3999/a_1.scala
new file mode 100644
index 0000000000..25366ee9c4
--- /dev/null
+++ b/test/files/pos/t3999/a_1.scala
@@ -0,0 +1,9 @@
+package foo
+
+class Outside
+
+package object bar {
+ class Val(b: Boolean)
+ implicit def boolean2Val(b: Boolean) = new Val(b)
+ implicit def boolean2Outside(b: Boolean) = new Outside
+} \ No newline at end of file
diff --git a/test/files/pos/t3999/b_2.scala b/test/files/pos/t3999/b_2.scala
new file mode 100644
index 0000000000..1af82c8c5b
--- /dev/null
+++ b/test/files/pos/t3999/b_2.scala
@@ -0,0 +1,7 @@
+package foo
+package bar
+
+class A {
+ val s: Val = false
+ val o: Outside = false
+} \ No newline at end of file