summaryrefslogtreecommitdiff
path: root/test/files/pos/t8862a.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-09-25 11:05:09 +1000
committerJason Zaugg <jzaugg@gmail.com>2014-11-07 11:40:03 +1000
commit2d8f919389fa33a554c5fb828bfa040f1b2531e4 (patch)
treee1286b71effedc5104d07348b54eebe37dc456ab /test/files/pos/t8862a.scala
parentc12a9b7bf8dc423783dd02eb0e4c477c86de96df (diff)
downloadscala-2d8f919389fa33a554c5fb828bfa040f1b2531e4.tar.gz
scala-2d8f919389fa33a554c5fb828bfa040f1b2531e4.tar.bz2
scala-2d8f919389fa33a554c5fb828bfa040f1b2531e4.zip
SI-8862 Fix treatment of inherited implicits in package objects
Two spots in implicit search fell prey to a trap with package objects. Members of a package object are entered into the scope of the enclosing package, but that doesn't form a suitable prefix for determing the member type. A REPL transcript paints a picture that speaks a 1000 words: ``` scala> :paste -raw // Entering paste mode (ctrl-D to finish) package p { class C[A] { def foo: A = ??? }; object `package` extends C[String] } // Exiting paste mode, now interpreting. scala> val p = rootMirror.getPackageIfDefined("p") warning: there was one deprecation warning; re-run with -deprecation for details p: $r.intp.global.Symbol = package p scala> p.info.decls res0: $r.intp.global.Scope = Scopes(class C, package object p, method foo) scala> val foo = p.info.decl(TermName("foo")) foo: $r.intp.global.Symbol = method foo scala> p.typeOfThis memberType foo res1: $r.intp.global.Type = => A scala> val fooOwner = foo.owner fooOwner: $r.intp.global.Symbol = class C scala> p.info.decl(nme.PACKAGE).typeOfThis memberType foo res3: $r.intp.global.Type = => String ``` This commit detects if we find an implicit in a package module, and then uses the self type of the corresponding package object as the prefix for the `ImplicitInfo`. This is done in both `Context.implicitss` (which collects in-scope implicits), and in `companionImplicitMap` (which harvests them from the implicit scope.) In addition, it was necessary / possible to remove a special case that excluded package object implicits, the referenced tests for SI-3999 now pass without this.
Diffstat (limited to 'test/files/pos/t8862a.scala')
-rw-r--r--test/files/pos/t8862a.scala47
1 files changed, 47 insertions, 0 deletions
diff --git a/test/files/pos/t8862a.scala b/test/files/pos/t8862a.scala
new file mode 100644
index 0000000000..f9576707ba
--- /dev/null
+++ b/test/files/pos/t8862a.scala
@@ -0,0 +1,47 @@
+package p {
+
+ abstract class C[A] {
+ def x: A
+ implicit def oops: A = x
+ implicit def oopso: Option[A] = None
+ }
+
+ package q {
+
+ class Oops
+
+ object `package` extends C[Oops] {
+ override def x = new Oops
+ }
+
+ object Blah {
+ oops
+ oopso
+
+ // implicits found in enclosing context
+ implicitly[Oops]
+ implicitly[Option[Oops]]
+ }
+ }
+}
+
+package other {
+
+ object Blah {
+ // implicits found through this import
+ import p.q._
+
+ oops
+ oopso
+
+ implicitly[Oops]
+ implicitly[Option[Oops]]
+ }
+
+
+ object Blee {
+ // implicits found through the companion implicits
+ implicitly[p.q.Oops]
+ implicitly[Option[p.q.Oops]]
+ }
+}