aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2016-03-24 20:22:01 +0100
committerDmitry Petrashko <dark@d-d.me>2016-03-24 20:22:01 +0100
commit035aff45e89084290b8f67ca49007c3eac00f13f (patch)
treeda73d918daf133ad8ff012a0774eb82fd49bf413 /src
parent3e43c7f989c48c8e78eb6c7b5ae9bcb301a0c07d (diff)
parent28a2c76952c753ea2c3efacfad93c87a63227259 (diff)
downloaddotty-035aff45e89084290b8f67ca49007c3eac00f13f.tar.gz
dotty-035aff45e89084290b8f67ca49007c3eac00f13f.tar.bz2
dotty-035aff45e89084290b8f67ca49007c3eac00f13f.zip
Merge pull request #1104 from dotty-staging/spec-bugs
Improvements & bugs that were discovered while implementing specialization.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled2
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Memoize.scala9
-rw-r--r--src/dotty/tools/dotc/transform/MixinOps.scala18
4 files changed, 23 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled b/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled
index 65362f199..7b37c5881 100644
--- a/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled
+++ b/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled
@@ -30,7 +30,7 @@ import dotty.tools.dotc.transform.TreeTransforms.TransformerInfo
*/
class DropEmptyCompanions extends MiniPhaseTransform { thisTransform =>
import ast.tpd._
- override def phaseName = "dropEmpty"
+ override def phaseName = "dropEmptyCompanions"
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Flatten])
override def transformPackageDef(pdef: PackageDef)(implicit ctx: Context, info: TransformerInfo) = {
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index 3445b4c44..8d890902e 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -611,7 +611,7 @@ object Erasure extends TypeTestsCasts{
traverse(newStats, oldStats)
}
- private final val NoBridgeFlags = Flags.Accessor | Flags.Deferred | Flags.Lazy
+ private final val NoBridgeFlags = Flags.Accessor | Flags.Deferred | Flags.Lazy | Flags.ParamAccessor
/** Create a bridge DefDef which overrides a parent method.
*
diff --git a/src/dotty/tools/dotc/transform/Memoize.scala b/src/dotty/tools/dotc/transform/Memoize.scala
index b775496ae..1e4f8831b 100644
--- a/src/dotty/tools/dotc/transform/Memoize.scala
+++ b/src/dotty/tools/dotc/transform/Memoize.scala
@@ -68,6 +68,10 @@ import Decorators._
}
lazy val field = sym.field.orElse(newField).asTerm
+
+ def adaptToField(tree: Tree) =
+ if (tree.isEmpty) tree else tree.ensureConforms(field.info.widen)
+
if (sym.is(Accessor, butNot = NoFieldNeeded))
if (sym.isGetter) {
def skipBlocks(t: Tree): Tree = t match {
@@ -85,14 +89,15 @@ import Decorators._
case _ =>
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
if (isWildcardArg(rhs)) rhs = EmptyTree
- val fieldDef = transformFollowing(ValDef(field, rhs))
+
+ val fieldDef = transformFollowing(ValDef(field, adaptToField(rhs)))
val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field))(ctx.withOwner(sym), info))
Thicket(fieldDef, getterDef)
}
} else if (sym.isSetter) {
if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs } // this is intended as an assertion
field.setFlag(Mutable) // necessary for vals mixed in from Scala2 traits
- val initializer = Assign(ref(field), ref(tree.vparamss.head.head.symbol))
+ val initializer = Assign(ref(field), adaptToField(ref(tree.vparamss.head.head.symbol)))
cpy.DefDef(tree)(rhs = transformFollowingDeep(initializer)(ctx.withOwner(sym), info))
}
else tree // curiously, some accessors from Scala2 have ' ' suffixes. They count as
diff --git a/src/dotty/tools/dotc/transform/MixinOps.scala b/src/dotty/tools/dotc/transform/MixinOps.scala
index db89f939b..6cebf7197 100644
--- a/src/dotty/tools/dotc/transform/MixinOps.scala
+++ b/src/dotty/tools/dotc/transform/MixinOps.scala
@@ -41,11 +41,21 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
ctx.atPhase(thisTransform) { implicit ctx =>
cls.info.member(sym.name).hasAltWith(_.symbol == sym)
}
-
+
+ /** Does `method` need a forwarder to in class `cls`
+ * Method needs a forwarder in those cases:
+ * - there's a class defining a method with same signature
+ * - there are multiple traits defining method with same signature
+ */
def needsForwarder(meth: Symbol): Boolean = {
- lazy val overridenSymbols = meth.allOverriddenSymbols
- def needsDisambiguation = !overridenSymbols.forall(_ is Deferred)
- def hasNonInterfaceDefinition = overridenSymbols.forall(!_.owner.is(Trait))
+ lazy val competingMethods = cls.baseClasses.iterator
+ .filter(_ ne meth.owner)
+ .map(meth.overriddenSymbol)
+ .filter(_.exists)
+ .toList
+
+ def needsDisambiguation = competingMethods.exists(x=> !(x is Deferred)) // multiple implementations are available
+ def hasNonInterfaceDefinition = competingMethods.exists(!_.owner.is(Trait)) // there is a definition originating from class
meth.is(Method, butNot = PrivateOrAccessorOrDeferred) &&
isCurrent(meth) &&
(needsDisambiguation || hasNonInterfaceDefinition || meth.owner.is(Scala2x))