diff options
author | Paul Phillips <paulp@improving.org> | 2012-01-13 14:16:18 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-01-13 15:44:58 -0800 |
commit | d7981e784e11e8a5a9a761f28d90725d721c9475 (patch) | |
tree | 28f506c89eebfe3bb9d3e96227e9d7c047cd09f0 | |
parent | 66a3623d59a261830076c7ad2b04fbb82e415547 (diff) | |
download | scala-d7981e784e11e8a5a9a761f28d90725d721c9475.tar.gz scala-d7981e784e11e8a5a9a761f28d90725d721c9475.tar.bz2 scala-d7981e784e11e8a5a9a761f28d90725d721c9475.zip |
Fix for spurious implicit ambiguity with package objects.
Closes SI-3999. Review by @odersky.
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 18 | ||||
-rw-r--r-- | test/files/pos/t3999/a_1.scala | 9 | ||||
-rw-r--r-- | test/files/pos/t3999/b_2.scala | 7 |
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 |