aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeErasure.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Memoize.scala6
-rw-r--r--src/dotty/tools/dotc/transform/Mixin.scala10
-rw-r--r--src/dotty/tools/dotc/transform/ResolveSuper.scala4
-rw-r--r--tests/run/supercalls-traits.scala15
-rw-r--r--tests/run/traits-initialization.scala41
6 files changed, 70 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala
index 65bc5e57f..fac795ef8 100644
--- a/src/dotty/tools/dotc/core/TypeErasure.scala
+++ b/src/dotty/tools/dotc/core/TypeErasure.scala
@@ -164,7 +164,7 @@ object TypeErasure {
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx))
else erase.eraseInfo(tp, sym)(erasureCtx) match {
case einfo: MethodType if sym.isGetter && einfo.resultType.isRef(defn.UnitClass) =>
- defn.BoxedUnitClass.typeRef
+ MethodType(Nil, Nil, defn.BoxedUnitClass.typeRef)
case einfo =>
einfo
}
diff --git a/src/dotty/tools/dotc/transform/Memoize.scala b/src/dotty/tools/dotc/transform/Memoize.scala
index d96a52868..cbde1ef8a 100644
--- a/src/dotty/tools/dotc/transform/Memoize.scala
+++ b/src/dotty/tools/dotc/transform/Memoize.scala
@@ -50,15 +50,15 @@ import Decorators._
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
val sym = tree.symbol
-
+
def newField = ctx.newSymbol(
owner = ctx.owner,
name = sym.name.asTermName.fieldName,
flags = Private | (if (sym is Stable) EmptyFlags else Mutable),
info = sym.info.resultType,
coord = tree.pos).enteredAfter(thisTransform)
-
- lazy val field = sym.field.orElse(newField).asTerm
+
+ lazy val field = sym.field.orElse(newField).asTerm
if (sym.is(Accessor, butNot = NoFieldNeeded))
if (sym.isGetter) {
tree.rhs.changeOwnerAfter(sym, field, thisTransform)
diff --git a/src/dotty/tools/dotc/transform/Mixin.scala b/src/dotty/tools/dotc/transform/Mixin.scala
index 8470be2ef..d2e7943f8 100644
--- a/src/dotty/tools/dotc/transform/Mixin.scala
+++ b/src/dotty/tools/dotc/transform/Mixin.scala
@@ -152,8 +152,14 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
def traitInits(mixin: ClassSymbol): List[Tree] =
for (getter <- mixin.info.decls.filter(getr => getr.isGetter && !wasDeferred(getr)).toList)
yield {
- // transformFollowing call is needed to make memoize & lazy vals run
- transformFollowing(DefDef(implementation(getter.asTerm), superRef(initializer(getter)).appliedToNone))
+ // transformFollowing call is needed to make memoize & lazy vals run
+ val rhs = transformFollowing(superRef(initializer(getter)).appliedToNone)
+ // isCurrent: getter is a member of implementing class
+ val isCurrent = getter.is(ExpandedName) || ctx.atPhase(thisTransform) { implicit ctx =>
+ cls.info.member(getter.name).suchThat(_.isGetter).symbol == getter
+ }
+ if (isCurrent) transformFollowing(DefDef(implementation(getter.asTerm), rhs))
+ else rhs
}
def setters(mixin: ClassSymbol): List[Tree] =
diff --git a/src/dotty/tools/dotc/transform/ResolveSuper.scala b/src/dotty/tools/dotc/transform/ResolveSuper.scala
index 9c0e34256..0f1c448d9 100644
--- a/src/dotty/tools/dotc/transform/ResolveSuper.scala
+++ b/src/dotty/tools/dotc/transform/ResolveSuper.scala
@@ -83,7 +83,7 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
def methodOverrides(mixin: ClassSymbol): List[Tree] = {
def isOverridden(meth: Symbol) = meth.overridingSymbol(cls).is(Method, butNot = Deferred)
def needsDisambiguation(meth: Symbol): Boolean =
- meth.is(Method, butNot = PrivateOrDeferred) &&
+ meth.is(Method, butNot = PrivateOrAccessorOrDeferred) &&
!isOverridden(meth) &&
!meth.allOverriddenSymbols.forall(_ is Deferred)
for (meth <- mixin.info.decls.toList if needsDisambiguation(meth))
@@ -107,5 +107,5 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
else ddef
}
- private val PrivateOrDeferred = Private | Deferred
+ private val PrivateOrAccessorOrDeferred = Private | Accessor | Deferred
}
diff --git a/tests/run/supercalls-traits.scala b/tests/run/supercalls-traits.scala
new file mode 100644
index 000000000..09e841f46
--- /dev/null
+++ b/tests/run/supercalls-traits.scala
@@ -0,0 +1,15 @@
+trait A {
+ def foo = 1
+}
+
+trait B {
+ def foo = 2
+}
+
+class C extends A with B {
+ override def foo = super[A].foo + super[B].foo
+}
+
+object Test {
+ def main(args: Array[String]) = assert(new C().foo == 3)
+}
diff --git a/tests/run/traits-initialization.scala b/tests/run/traits-initialization.scala
new file mode 100644
index 000000000..fdddc8f44
--- /dev/null
+++ b/tests/run/traits-initialization.scala
@@ -0,0 +1,41 @@
+object store {
+ var str = ""
+}
+
+import store._
+
+trait A {
+ str += "a"
+ val i = 2
+ val s = str += 'A'
+ str += '1'
+}
+
+trait B extends A {
+ str += 'b'
+ override val i = 3
+ override val s = str += 'B'
+ str += '2'
+}
+
+class D(sup: Unit) extends A {
+ str += 'd'
+ override val i = 4
+ override val s = str += 'D'
+ str += '3'
+}
+
+class E(sup: Unit) extends A with B {
+ str += 'd'
+ override val i = 5
+ override val s = str += 'E'
+ str += '3'
+}
+
+
+object Test extends D({str += "Z"}) with B {
+ // should only have 2 fields
+ str += 'E'
+ def main(args: Array[String]) = assert(str == "ZaA1dD3bB2E4", str)
+ str += '4'
+}