diff options
author | Paul Phillips <paulp@improving.org> | 2012-12-15 16:38:10 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-12-15 19:40:05 -0800 |
commit | 8aae61180c3edab97c653dbc7096a439f5c3da12 (patch) | |
tree | 83e392fdefa9de398f42b0aedb57376423ff0332 /test/files/run/no-pickle-skolems | |
parent | e14917528e1c080a7f10785e21de36f3a7769718 (diff) | |
download | scala-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.scala | 5 | ||||
-rw-r--r-- | test/files/run/no-pickle-skolems/Test_2.scala | 37 |
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!") + } +} |