aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/TypeErasure.scala19
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala24
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala28
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: