summaryrefslogtreecommitdiff
path: root/test/files/run/no-pickle-skolems
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-12-15 16:38:10 -0800
committerPaul Phillips <paulp@improving.org>2012-12-15 19:40:05 -0800
commit8aae61180c3edab97c653dbc7096a439f5c3da12 (patch)
tree83e392fdefa9de398f42b0aedb57376423ff0332 /test/files/run/no-pickle-skolems
parente14917528e1c080a7f10785e21de36f3a7769718 (diff)
downloadscala-8aae61180c3edab97c653dbc7096a439f5c3da12.tar.gz
scala-8aae61180c3edab97c653dbc7096a439f5c3da12.tar.bz2
scala-8aae61180c3edab97c653dbc7096a439f5c3da12.zip
Deskolemize type skolems before pickling.
Lex Spoon noticed what appeared to be duplicate symbols in methods read from classfiles. The duplicates turned out to be type skolems, which because they're not supposed to be pickled in the first place (right?) are unpickled without turning back into skolems. Now pickler is careful to deskolemize before writing anything down. The effort implied by test case is more than can possibly be justified for this obscure compiler corner, but I'll chalk it up to reflection exploration.
Diffstat (limited to 'test/files/run/no-pickle-skolems')
-rw-r--r--test/files/run/no-pickle-skolems/Source_1.scala5
-rw-r--r--test/files/run/no-pickle-skolems/Test_2.scala37
2 files changed, 42 insertions, 0 deletions
diff --git a/test/files/run/no-pickle-skolems/Source_1.scala b/test/files/run/no-pickle-skolems/Source_1.scala
new file mode 100644
index 0000000000..1b4cbfa788
--- /dev/null
+++ b/test/files/run/no-pickle-skolems/Source_1.scala
@@ -0,0 +1,5 @@
+package s
+
+trait Foo { def to[CC[X]](implicit cc: CC[Int]): Unit }
+
+class Bar extends Foo { def to[CC[X]](implicit cc: CC[Int]): Unit = ??? }
diff --git a/test/files/run/no-pickle-skolems/Test_2.scala b/test/files/run/no-pickle-skolems/Test_2.scala
new file mode 100644
index 0000000000..90bb4c4f88
--- /dev/null
+++ b/test/files/run/no-pickle-skolems/Test_2.scala
@@ -0,0 +1,37 @@
+import scala.reflect.runtime.universe._
+
+object Test {
+ /** Collects symbols by the given name, even if they're not
+ * named CC.
+ */
+ def collectSymbols[T: TypeTag](inMethod: TermName, name: String): List[String] = {
+ val m = typeOf[T] member inMethod typeSignatureIn typeOf[T]
+ var buf: List[Symbol] = Nil
+ var seen: Set[Symbol] = Set()
+ def id(s: Symbol): Int = s.asInstanceOf[{ def id: Int }].id
+
+ def check(s: Symbol) {
+ if (!seen(s)) {
+ seen += s
+ if (s.name.toString == name) buf ::= s
+ }
+ }
+ def loop(t: Type) {
+ t match {
+ case TypeRef(pre, sym, args) => loop(pre) ; check(sym) ; args foreach loop
+ case PolyType(tparams, restpe) => tparams foreach { tp => check(tp) ; check(tp.owner) ; loop(tp.typeSignature) } ; loop(restpe)
+ case MethodType(params, restpe) => params foreach { p => check(p) ; loop(p.typeSignature) } ; loop(restpe)
+ case _ =>
+ }
+ }
+ loop(m)
+
+ buf.reverse.distinct map (s => s.name + "#" + id(s))
+ }
+
+ def main(args: Array[String]): Unit = {
+ val syms = collectSymbols[s.Bar]("to", "CC")
+ assert(syms.size == 1, syms)
+ println("OK!")
+ }
+}