diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-02-15 15:37:55 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-03-31 14:49:23 +0200 |
commit | 07833e93f62cbe6d866300475288e8a763a36198 (patch) | |
tree | ca68403be647950d5a69eda1ba7fef5938f66656 /src/dotty/tools/dotc/transform/TailRec.scala | |
parent | 80b12473d7e7c5551ed7b13a835f239445662813 (diff) | |
download | dotty-07833e93f62cbe6d866300475288e8a763a36198.tar.gz dotty-07833e93f62cbe6d866300475288e8a763a36198.tar.bz2 dotty-07833e93f62cbe6d866300475288e8a763a36198.zip |
FullParametrization: allow to have $this of ThisType.
TailRec methods remain members of enclosing class,
it means that they can refer to methods that require this.type.
It means that tailrec, unlike value classes is not allowed to widen
type of $this to it's full self type.
Fixes #1089
Diffstat (limited to 'src/dotty/tools/dotc/transform/TailRec.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/TailRec.scala | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala index 58fe7a6c9..558206960 100644 --- a/src/dotty/tools/dotc/transform/TailRec.scala +++ b/src/dotty/tools/dotc/transform/TailRec.scala @@ -77,7 +77,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete private def mkLabel(method: Symbol, abstractOverClass: Boolean)(implicit c: Context): TermSymbol = { val name = c.freshName(labelPrefix) - c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass)) + c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass, liftThisType = true)) } override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { @@ -112,7 +112,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete if (rewrote) { val dummyDefDef = cpy.DefDef(tree)(rhs = rhsSemiTransformed) val res = fullyParameterizedDef(label, dummyDefDef, abstractOverClass = defIsTopLevel) - val call = forwarder(label, dd, abstractOverClass = defIsTopLevel) + val call = forwarder(label, dd, abstractOverClass = defIsTopLevel, liftThisType = true) Block(List(res), call) } else { if (mandatory) @@ -175,8 +175,8 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete case x => (x, x, accArgs, accT, x.symbol) } - val (reciever, call, arguments, typeArguments, symbol) = receiverArgumentsAndSymbol(tree) - val recv = noTailTransform(reciever) + val (prefix, call, arguments, typeArguments, symbol) = receiverArgumentsAndSymbol(tree) + val recv = noTailTransform(prefix) val targs = typeArguments.map(noTailTransform) val argumentss = arguments.map(noTailTransforms) @@ -215,12 +215,12 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete targs ::: classTypeArgs.map(x => ref(x.typeSymbol)) } else targs - val method = Apply(if (callTargs.nonEmpty) TypeApply(Ident(label.termRef), callTargs) else Ident(label.termRef), - List(receiver)) + val method = if (callTargs.nonEmpty) TypeApply(Ident(label.termRef), callTargs) else Ident(label.termRef) + val thisPassed = method appliedTo(receiver.ensureConforms(method.tpe.widen.firstParamTypes.head)) val res = - if (method.tpe.widen.isParameterless) method - else argumentss.foldLeft(method) { + if (thisPassed.tpe.widen.isParameterless) thisPassed + else argumentss.foldLeft(thisPassed) { (met, ar) => Apply(met, ar) // Dotty deviation no auto-detupling yet. } res |