diff options
Diffstat (limited to 'src/library/scala/reflect/generic/UnPickler.scala')
-rwxr-xr-x | src/library/scala/reflect/generic/UnPickler.scala | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/library/scala/reflect/generic/UnPickler.scala b/src/library/scala/reflect/generic/UnPickler.scala index 7b7c34a767..86b73cf5fd 100755 --- a/src/library/scala/reflect/generic/UnPickler.scala +++ b/src/library/scala/reflect/generic/UnPickler.scala @@ -281,7 +281,7 @@ abstract class UnPickler { sym case MODULEsym => - val clazz = at(inforef, readType).typeSymbol + val clazz = at(inforef, () => readType()).typeSymbol // after the NMT_TRANSITION period, we can leave off the () => ... () if (isModuleRoot) moduleRoot else { val m = owner.newModule(name, clazz) @@ -298,8 +298,13 @@ abstract class UnPickler { }) } - /** Read a type */ - protected def readType(): Type = { + /** Read a type + * + * @param forceProperType is used to ease the transition to NullaryMethodTypes (commentmarker: NMT_TRANSITION) + * the flag say that a type of kind * is expected, so that PolyType(tps, restpe) can be disambiguated to PolyType(tps, NullaryMethodType(restpe)) + * (if restpe is not a ClassInfoType, a MethodType or a NullaryMethodType, which leaves TypeRef/SingletonType -- the latter would make the polytype a type constructor) + */ + protected def readType(forceProperType: Boolean = false): Type = { val tag = readByte() val end = readNat() + readIndex (tag: @switch) match { @@ -341,7 +346,19 @@ abstract class UnPickler { case POLYtpe => val restpe = readTypeRef() val typeParams = until(end, readSymbolRef) - PolyType(typeParams, restpe) + if(typeParams nonEmpty) { + // NMT_TRANSITION: old class files denoted a polymorphic nullary method as PolyType(tps, restpe), we now require PolyType(tps, NullaryMethodType(restpe)) + // when a type of kind * is expected (forceProperType is true), we know restpe should be wrapped in a NullaryMethodType (if it wasn't suitably wrapped yet) + def transitionNMT(restpe: Type) = { + val resTpeCls = restpe.getClass.toString // what's uglier than isInstanceOf? right! -- isInstanceOf does not work since the concrete types are defined in the compiler (not in scope here) + if(forceProperType /*&& pickleformat < 2.9 */ && !(resTpeCls.endsWith("MethodType"))) { assert(!resTpeCls.contains("ClassInfoType")) + NullaryMethodType(restpe) } + else restpe + } + PolyType(typeParams, transitionNMT(restpe)) + } + else + NullaryMethodType(restpe) case EXISTENTIALtpe => val restpe = readTypeRef() ExistentialType(until(end, readSymbolRef), restpe) @@ -352,7 +369,7 @@ abstract class UnPickler { typeRef = readNat() s } else NoSymbol // selfsym can go. - val tp = at(typeRef, readType) + val tp = at(typeRef, () => readType(forceProperType)) // NMT_TRANSITION val annots = until(end, readAnnotationRef) if (selfsym == NoSymbol) AnnotatedType(annots, tp, selfsym) else tp @@ -739,7 +756,7 @@ abstract class UnPickler { /* Read a reference to a pickled item */ protected def readNameRef(): Name = at(readNat(), readName) protected def readSymbolRef(): Symbol = at(readNat(), readSymbol) - protected def readTypeRef(): Type = at(readNat(), readType) + protected def readTypeRef(): Type = at(readNat(), () => readType()) // after the NMT_TRANSITION period, we can leave off the () => ... () protected def readConstantRef(): Constant = at(readNat(), readConstant) protected def readAnnotationRef(): AnnotationInfo = at(readNat(), readAnnotation) protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers) |