summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-12-05 00:07:28 +0100
committerJason Zaugg <jzaugg@gmail.com>2012-12-05 00:07:28 +0100
commit90efa6bc35f0e4e1d37389af5a681836a03b68e5 (patch)
tree59f6161c0164b065fbf0340f153f68247d99a137
parentfd57069a3a49de1757a518b573a0cd8cb98bbbd5 (diff)
downloadscala-90efa6bc35f0e4e1d37389af5a681836a03b68e5.tar.gz
scala-90efa6bc35f0e4e1d37389af5a681836a03b68e5.tar.bz2
scala-90efa6bc35f0e4e1d37389af5a681836a03b68e5.zip
SI-3995 Exclude companions with an existential prefix.
In `(qual: Q).apply(expr)` where `expr` must be implictily converted to a path dependent type `T` defined in `qual`, we were looking for companion implicits via a path prefixed by an existential skolem `_1`. These aren't much good to us, as when we try to feed them into `mkAttributedQualifer`, a crash rightly ensues. This commit excludes companions prefixed by an existentially bound path.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala6
-rw-r--r--test/files/neg/t3995.check6
-rw-r--r--test/files/neg/t3995.scala25
3 files changed, 34 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index fc10f68454..68db812ad7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -935,8 +935,8 @@ trait Implicits {
* - for alias types and abstract types, we take instead the parts
* - of their upper bounds.
* @return For those parts that refer to classes with companion objects that
- * can be accessed with unambiguous stable prefixes, the implicits infos
- * which are members of these companion objects.
+ * can be accessed with unambiguous stable prefixes that are not existentially
+ * bound, the implicits infos which are members of these companion objects.
*/
private def companionImplicitMap(tp: Type): InfoMap = {
@@ -952,7 +952,7 @@ trait Implicits {
infoMap(sym) = List() // ambiguous prefix - ignore implicit members
}
case None =>
- if (pre.isStable) {
+ if (pre.isStable && !pre.typeSymbol.isExistentiallyBound) {
val companion = companionSymbolOf(sym, context)
companion.moduleClass match {
case mc: ModuleClassSymbol =>
diff --git a/test/files/neg/t3995.check b/test/files/neg/t3995.check
new file mode 100644
index 0000000000..844150a528
--- /dev/null
+++ b/test/files/neg/t3995.check
@@ -0,0 +1,6 @@
+t3995.scala:24: error: type mismatch;
+ found : String("")
+ required: _1.F0 where val _1: Lift
+ (new Lift).apply("")
+ ^
+one error found
diff --git a/test/files/neg/t3995.scala b/test/files/neg/t3995.scala
new file mode 100644
index 0000000000..8eb4698aaa
--- /dev/null
+++ b/test/files/neg/t3995.scala
@@ -0,0 +1,25 @@
+class Lift {
+ def apply(f: F0) {}
+
+ class F0
+ object F0 {
+ implicit def f2f0(fn: String): F0 = ???
+ }
+}
+
+object Test {
+ val l = new Lift
+ val f = ""
+
+ "": l.F0 // okay
+
+ // fails trying to mkAttributedQualifier for pre = Skolem(_1 <: Lift with Singletom).F0
+ // should this even have shown up in `companionImplicitMap`? It says that:
+ //
+ // "@return For those parts that refer to classes with companion objects that
+ // can be accessed with unambiguous stable prefixes, the implicits infos
+ // which are members of these companion objects."
+ //
+ // The skolem is stable, but it doen't seem much good to us
+ (new Lift).apply("")
+}