From f62e280825422c1e64c2427bc5958869662701ca Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Fri, 7 Feb 2014 11:52:55 +0100 Subject: SI-8244 Fix raw type regression under separate compilation In #1901, handling of raw types encountered in signatures during class file parsing was changed to work in the same manner as `classExistentialType`, by using `existentialAbstraction(cls.tparms, cls.tpe_*)` But this never creates fresh existential symbols, and just sticks the class type parameters it `quantified`: scala> trait T[A <: String] defined trait T scala> val cls = typeOf[T[_]].typeSymbol cls = trait T#101864 scala> cls.typeParams res0 = List(type A#101865) scala> cls.tpe_* res1 = T#101864[A#101865] scala> classExistentialType(cls) res3 = T#101864[_ <: String#7209] scala> val ExistentialType(quantified, result) = res3 List(type A#101865) In the enclosed test case, this class type parameter was substituted during `typeOf[X] memberType sym`, which led us unsoundly thinking that `Raw[_]` was `Raw[X]`. I've added a TODO comment to review the other usages of `classExistentialType`. Test variations include joint and separate compilation, and the corresponding Scala-only code. All fail with type errors now, as we expect. I've also added a distillation of a bootstrap error that failed when I forgot to wrap the `existentialType`. --- .../scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 664645e53e..2f9cc01c0b 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -665,8 +665,11 @@ abstract class ClassfileParser { // so have to check unsafeTypeParams.isEmpty before worrying about raw type case below, // or we'll create a boatload of needless existentials. else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp - // raw type - existentially quantify all type parameters - else debuglogResult(s"raw type from $classSym")(unsafeClassExistentialType(classSym)) + else debuglogResult(s"raw type from $classSym"){ + // raw type - existentially quantify all type parameters + val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) + newExistentialType(eparams, typeRef(pre, classSym, eparams.map(_.tpeHK))) + } case tp => assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp") tp -- cgit v1.2.3