aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/Erasure.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/transform/Erasure.scala')
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala28
1 files changed, 22 insertions, 6 deletions
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: