aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-12-10 11:11:44 +0100
committerMartin Odersky <odersky@gmail.com>2015-12-14 14:30:09 +0100
commit2a3f78673afe581fffec7f88039ba27a71ed2fe2 (patch)
treea238341917de2e2e0a13a20493115bd1d8e56333 /src/dotty
parent8203177068d02327e6c8ca576d2c704204500e27 (diff)
downloaddotty-2a3f78673afe581fffec7f88039ba27a71ed2fe2.tar.gz
dotty-2a3f78673afe581fffec7f88039ba27a71ed2fe2.tar.bz2
dotty-2a3f78673afe581fffec7f88039ba27a71ed2fe2.zip
Fix sleeper bug in ParamForwarding
ParamForwarding converts some parameters to nullary methods, yet it does not update the references to these parameters. Their signature is still NotAMethod, which is wrong. Causes subtle differences in peckle tests: a param accessor get type T before pickling (which is wrong), gets => T when reading back (which is right). Test case in pickling/selfSym.scala.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala3
-rw-r--r--src/dotty/tools/dotc/transform/ParamForwarding.scala11
-rw-r--r--src/dotty/tools/dotc/transform/PostTyper.scala13
-rw-r--r--src/dotty/tools/dotc/transform/SuperAccessors.scala3
4 files changed, 23 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index c859fae3e..42d06c2ab 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -585,6 +585,9 @@ object Flags {
/** A private[this] parameter accessor */
final val PrivateLocalParamAccessor = allOf(Private, Local, ParamAccessor)
+ /** A parameter forwarder */
+ final val ParamForwarder = allOf(Method, Stable, ParamAccessor)
+
/** A private[this] parameter */
final val PrivateLocalParam = allOf(Private, Local, Param)
diff --git a/src/dotty/tools/dotc/transform/ParamForwarding.scala b/src/dotty/tools/dotc/transform/ParamForwarding.scala
index 2e6a97bcf..9571c387b 100644
--- a/src/dotty/tools/dotc/transform/ParamForwarding.scala
+++ b/src/dotty/tools/dotc/transform/ParamForwarding.scala
@@ -80,4 +80,15 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
cpy.Template(impl)(body = fwd(impl.body)(ctx.withPhase(thisTransformer)))
}
+
+ def adaptRef[T <: RefTree](tree: T)(implicit ctx: Context): T = tree.tpe match {
+ case tpe: TermRefWithSignature
+ if tpe.sig == Signature.NotAMethod && tpe.symbol.is(Method) =>
+ // It's a param forwarder; adapt the signature
+ tree.withType(
+ TermRef.withSig(tpe.prefix, tpe.name, tpe.prefix.memberInfo(tpe.symbol).signature))
+ .asInstanceOf[T]
+ case _ =>
+ tree
+ }
}
diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala
index 75c98ae8a..3266d3a02 100644
--- a/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -157,10 +157,10 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
case tree: Ident =>
tree.tpe match {
case tpe: ThisType => This(tpe.cls).withPos(tree.pos)
- case _ => tree
+ case _ => paramFwd.adaptRef(tree)
}
case tree: Select =>
- transformSelect(tree, Nil)
+ transformSelect(paramFwd.adaptRef(tree), Nil)
case tree @ TypeApply(sel: Select, args) =>
val args1 = transform(args)
val sel1 = transformSelect(sel, args1)
@@ -170,11 +170,12 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
case tree: Template =>
val saved = parentNews
parentNews ++= tree.parents.flatMap(newPart)
- try
+ try {
+ val templ1 = paramFwd.forwardParamAccessors(tree)
synthMth.addSyntheticMethods(
- paramFwd.forwardParamAccessors(
- superAcc.wrapTemplate(tree)(
- super.transform(_).asInstanceOf[Template])))
+ superAcc.wrapTemplate(templ1)(
+ super.transform(_).asInstanceOf[Template]))
+ }
finally parentNews = saved
case tree: DefDef =>
transformAnnots(tree)
diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 31cfef914..2febd2673 100644
--- a/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -99,7 +99,8 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
assert(sup.symbol.exists, s"missing symbol in $sel: ${sup.tpe}")
val clazz = sup.symbol.asClass
- if ((sym.isTerm) && !(sym is Method) || (sym is Accessor))
+ if (sym.isTerm && !sym.is(Method, butNot = Accessor) && !ctx.owner.is(ParamForwarder))
+ // ParamForwaders as installed ParamForwarding.scala do use super calls to vals
ctx.error(s"super may be not be used on ${sym.underlyingSymbol}", sel.pos)
else if (isDisallowed(sym))
ctx.error(s"super not allowed here: use this.${sel.name.decode} instead", sel.pos)