diff options
author | Martin Odersky <odersky@gmail.com> | 2015-12-10 11:11:44 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-12-14 14:30:09 +0100 |
commit | 2a3f78673afe581fffec7f88039ba27a71ed2fe2 (patch) | |
tree | a238341917de2e2e0a13a20493115bd1d8e56333 /src | |
parent | 8203177068d02327e6c8ca576d2c704204500e27 (diff) | |
download | dotty-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')
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ParamForwarding.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/PostTyper.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/SuperAccessors.scala | 3 |
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) |