diff options
author | Martin Odersky <odersky@gmail.com> | 2013-10-27 18:33:57 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-10-27 18:33:57 +0100 |
commit | 52a8a0aec9da8a4eaa3faf95ec7acd3ecfbabf53 (patch) | |
tree | 7f029c717a8f8ea0787f669412ce2047e68a630d /src/dotty/tools/dotc/core | |
parent | 41e7d9d46177650d23447f99989e8347aca56e71 (diff) | |
download | dotty-52a8a0aec9da8a4eaa3faf95ec7acd3ecfbabf53.tar.gz dotty-52a8a0aec9da8a4eaa3faf95ec7acd3ecfbabf53.tar.bz2 dotty-52a8a0aec9da8a4eaa3faf95ec7acd3ecfbabf53.zip |
Fixed unpickling of polymorphic constructors.
Constructors of parameterized classes now get polymorphic types when unpickled, as is the case when defining them or when reading them from a Java classfile. This caused a ripple of other faults which this commit also fixes.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 20 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 6 |
4 files changed, 33 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index 221f5c160..8b7cb7bd7 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -61,6 +61,8 @@ object Annotations { apply(defn.ChildAnnot.typeConstructor.appliedTo(NamedType(sym.owner.thisType, sym.name).withDenot(sym)), Nil) } - def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) = - Annotation(defn.ThrowsAnnot, Ident(cls.symTypeRef)) + def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) = { + val tref = cls.symTypeRef + Annotation(defn.ThrowsAnnot.typeConstructor.appliedTo(tref), Ident(tref)) + } }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 5f60454b5..ea4d1f572 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -901,6 +901,17 @@ object Types { if (buf == null) Nil else buf.toList } + /** The core type without any type arguments. + * @param `typeArgs` must be the type arguments of this type. + */ + final def withoutArgs(typeArgs: List[Type]): Type = typeArgs match { + case _ :: typeArgs1 => + val RefinedType(tycon, _) = this + tycon.withoutArgs(typeArgs.tail) + case nil => + this + } + /** If this is the image of a type argument to type parameter `tparam`, * recover the type argument, otherwise NoType. */ @@ -1504,10 +1515,17 @@ object Types { def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): RefinedType = { def originalName = parent.typeParams.apply(refinedName.hkParamIndex).name + def checkForTypeParams(tpe: Type): Boolean = tpe match { + case tpe: NamedType => tpe.symbol.isCompleted + case ThisType(cls) => cls.isCompleted + case tpe: BoundType => false + case tp: TypeProxy => checkForTypeParams(tp.underlying) + case _ => true + } if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo)) this else if (refinedName.isHkParamName && - parent.typeSymbol.isCompleted && // to avoid cyclic reference errors + checkForTypeParams(parent) && // to avoid cyclic reference errors refinedName.hkParamIndex < typeParams.length && originalName != refinedName) derivedRefinedType(parent, originalName, refinedInfo) diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index b65fc55bb..a641e10cc 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -174,7 +174,7 @@ class ClassfileParser( val isEnum = (jflags & JAVA_ACC_ENUM) != 0 val name = pool.getName(in.nextChar) val isConstructor = name eq nme.CONSTRUCTOR - + /** Strip leading outer param from constructor. * Todo: Also strip trailing access tag for private inner constructors? */ @@ -190,10 +190,9 @@ class ClassfileParser( */ def normalizeConstructorInfo() = { val mt @ MethodType(paramnames, paramtypes) = denot.info - val typeParams = classRoot.typeParams - val rt = classRoot.typeConstructor appliedTo (typeParams map (_.symRef)) - denot.info = PolyType.fromSymbols(typeParams, - mt.derivedMethodType(paramnames, paramtypes, rt)) + val rt = classRoot.typeConstructor appliedTo (classRoot.typeParams map (_.symRef)) + denot.info = mt.derivedMethodType(paramnames, paramtypes, rt) + addConstructorTypeParams(denot) } denot.info = pool.getType(in.nextChar) diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 4570d0654..cc777ce9b 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -62,6 +62,11 @@ object UnPickler { case tp => tp } + def addConstructorTypeParams(denot: SymDenotation)(implicit ctx: Context) = { + assert(denot.isConstructor) + denot.info = PolyType.fromSymbols(denot.owner.typeParams, denot.info) + } + /** Convert array parameters denoting a repeated parameter of a Java method * to `JavaRepeatedParamClass` types. */ @@ -497,6 +502,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: case denot => val tp1 = depoly(tp, denot) denot.info = if (tag == ALIASsym) TypeAlias(tp1) else tp1 + if (denot.isConstructor) addConstructorTypeParams(denot) if (atEnd) { assert(!(denot is SuperAccessor), denot) } else { |