diff options
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/TypeErasure.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/Parsers.scala | 24 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 28 |
4 files changed, 47 insertions, 26 deletions
diff --git a/src/dotty/tools/dotc/TypeErasure.scala b/src/dotty/tools/dotc/TypeErasure.scala index 7920667e7..3f9149214 100644 --- a/src/dotty/tools/dotc/TypeErasure.scala +++ b/src/dotty/tools/dotc/TypeErasure.scala @@ -317,9 +317,19 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild if (cls is Package) tp else { def eraseTypeRef(p: TypeRef) = this(p).asInstanceOf[TypeRef] - val parents: List[TypeRef] = + val parents: List[TypeRef] = { if ((cls eq defn.ObjectClass) || cls.isPrimitiveValueClass) Nil - else removeLaterObjects(classParents.mapConserve(eraseTypeRef)) + else { + def normalize(trs: List[TypeRef])(implicit ctx: Context): List[TypeRef] = trs match { + case tr :: trs1 => + assert(!tr.classSymbol.is(Trait), cls) + val tr1 = if (cls is Trait) defn.ObjectClass.typeRef else tr + tr1 :: trs1.filterNot(_ isRef defn.ObjectClass) + case nil => nil + } + normalize(classParents.mapConserve(eraseTypeRef)) + } + } val erasedDecls = decls.filteredScope(d => !d.isType || d.isClass) tp.derivedClassInfo(NoPrefix, parents, erasedDecls, erasedRef(tp.selfType)) // can't replace selftype by NoType because this would lose the sourceModule link @@ -376,11 +386,6 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild cls } - private def removeLaterObjects(trs: List[TypeRef])(implicit ctx: Context): List[TypeRef] = trs match { - case tr :: trs1 => tr :: trs1.filterNot(_ isRef defn.ObjectClass) - case nil => nil - } - /** The name of the type as it is used in `Signature`s. * Need to ensure correspondence with erasure! */ diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 14baa0b96..895d41516 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -262,7 +262,7 @@ class Definitions { lazy val ByNameParamClass2x = specialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, AnyType) lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, AnyType) - lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, SeqType) + lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, ObjectType, SeqType) // fundamental classes lazy val StringClass = ctx.requiredClass("java.lang.String") diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index e8a6fd815..b7028430b 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1777,23 +1777,23 @@ object Parsers { } } - /** TmplDef ::= ([`case'] `class' | `trait') ClassDef + /** TmplDef ::= ([`case'] `class' | `trait') ClassDef * | [`case'] `object' ObjectDef */ def tmplDef(start: Int, mods: Modifiers): Tree = in.token match { case TRAIT => classDef(posMods(start, mods | Trait)) - case CLASS => - classDef(posMods(start, mods)) - case CASECLASS => - classDef(posMods(start, mods | Case)) - case OBJECT => - objectDef(posMods(start, mods | Module)) - case CASEOBJECT => - objectDef(posMods(start, mods | Case | Module)) - case _ => - syntaxErrorOrIncomplete("expected start of definition") - EmptyTree + case CLASS => + classDef(posMods(start, mods)) + case CASECLASS => + classDef(posMods(start, mods | Case)) + case OBJECT => + objectDef(posMods(start, mods | Module)) + case CASEOBJECT => + objectDef(posMods(start, mods | Case | Module)) + case _ => + syntaxErrorOrIncomplete("expected start of definition") + EmptyTree } /** ClassDef ::= Id [ClsTypeParamClause] diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 23f1aada9..2b00cd8af 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -293,6 +293,18 @@ object Erasure extends TypeTestsCasts{ else assignType(untpd.cpy.Select(tree)(qual, tree.name.primitiveArrayOp), qual) + def adaptIfSuper(qual: Tree): Tree = qual match { + case Super(thisQual, tpnme.EMPTY) => + val SuperType(thisType, supType) = qual.tpe + if (sym.owner is Flags.Trait) + cpy.Super(qual)(thisQual, sym.owner.asClass.name) + .withType(SuperType(thisType, sym.owner.typeRef)) + else + qual.withType(SuperType(thisType, thisType.firstParent)) + case _ => + qual + } + def recur(qual: Tree): Tree = { val qualIsPrimitive = qual.tpe.widen.isPrimitiveValueType val symIsPrimitive = sym.owner.isPrimitiveValueClass @@ -306,10 +318,13 @@ object Erasure extends TypeTestsCasts{ recur(unbox(qual, sym.owner.typeRef)) else if (sym.owner eq defn.ArrayClass) selectArrayMember(qual, erasure(tree.qualifier.typeOpt.widen.finalResultType)) - else if (qual.tpe.derivesFrom(sym.owner) || qual.isInstanceOf[Super]) - select(qual, sym) - else - recur(cast(qual, sym.owner.typeRef)) + else { + val qual1 = adaptIfSuper(qual) + if (qual1.tpe.derivesFrom(sym.owner) || qual1.isInstanceOf[Super]) + select(qual1, sym) + else + recur(cast(qual1, sym.owner.typeRef)) + } } recur(typed(tree.qualifier, AnySelectionProto)) @@ -325,7 +340,7 @@ object Erasure extends TypeTestsCasts{ outer.path(tree.symbol) } - private def runtimeCallWithProtoArgs(name: Name, pt: Type, args: Tree*)(implicit ctx: Context): Tree = { + private def runtimeCallWithProtoArgs(name: Name, pt: Type, args: Tree*)(implicit ctx: Context): Tree = { val meth = defn.runtimeMethod(name) val followingParams = meth.info.firstParamTypes.drop(args.length) val followingArgs = protoArgs(pt).zipWithConserve(followingParams)(typedExpr).asInstanceOf[List[tpd.Tree]] @@ -416,7 +431,8 @@ object Erasure extends TypeTestsCasts{ s"${oldSymbol.name(beforeCtx)} bridging with ${newSymbol.name}") val newOverridden = oldSymbol.denot.allOverriddenSymbols.toSet // TODO: clarify new <-> old in a comment; symbols are swapped here val oldOverridden = newSymbol.allOverriddenSymbols(beforeCtx).toSet // TODO: can we find a more efficient impl? newOverridden does not have to be a set! - val neededBridges = oldOverridden -- newOverridden + def stillInBaseClass(sym: Symbol) = ctx.owner derivesFrom sym.owner + val neededBridges = (oldOverridden -- newOverridden).filter(stillInBaseClass) var minimalSet = Set[Symbol]() // compute minimal set of bridges that are needed: |