aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/TailRec.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2016-02-15 15:37:55 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2016-03-31 14:49:23 +0200
commit07833e93f62cbe6d866300475288e8a763a36198 (patch)
treeca68403be647950d5a69eda1ba7fef5938f66656 /src/dotty/tools/dotc/transform/TailRec.scala
parent80b12473d7e7c5551ed7b13a835f239445662813 (diff)
downloaddotty-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.scala16
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