Skip to content

Commit 13f25af

Browse files
committed
Fix i321, tail call needs to be careful with abstracting over class type arguments.
Or it could lead to Ycheck error that was triggered in #321.
1 parent 78840c4 commit 13f25af

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

src/dotty/tools/dotc/transform/TailRec.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
7777
private def mkLabel(method: Symbol)(implicit c: Context): TermSymbol = {
7878
val name = c.freshName(labelPrefix)
7979

80-
c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass))
80+
c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass = false))
8181
}
8282

8383
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
@@ -109,8 +109,8 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
109109

110110
if (rewrote) {
111111
val dummyDefDef = cpy.DefDef(tree)(rhs = rhsSemiTransformed)
112-
val res = fullyParameterizedDef(label, dummyDefDef)
113-
val call = forwarder(label, dd)
112+
val res = fullyParameterizedDef(label, dummyDefDef, abstractOverClass = false)
113+
val call = forwarder(label, dd, abstractOverClass = false)
114114
Block(List(res), call)
115115
} else {
116116
if (mandatory)
@@ -204,9 +204,13 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
204204
c.debuglog("Rewriting tail recursive call: " + tree.pos)
205205
rewrote = true
206206
val reciever = noTailTransform(recv)
207-
val classTypeArgs = recv.tpe.baseTypeWithArgs(enclosingClass).argInfos
208-
val trz = classTypeArgs.map(x => ref(x.typeSymbol))
209-
val callTargs: List[tpd.Tree] = targs ::: trz
207+
208+
/*
209+
handling changed type arguments in sound way is hard, see test `i321`
210+
val classTypeArgs = recv.tpe.baseTypeWithArgs(enclosingClass).argInfos
211+
val trz = classTypeArgs.map(x => ref(x.typeSymbol))
212+
*/
213+
val callTargs: List[tpd.Tree] = targs
210214
val method = Apply(if (callTargs.nonEmpty) TypeApply(Ident(label.termRef), callTargs) else Ident(label.termRef),
211215
List(reciever))
212216

tests/pos/tailcall/i321.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class i321[T >: Null <: AnyRef] {
2+
3+
def mapconserve(f: T => Int): Int = {
4+
def loop(pending: T): Int = {
5+
val head1 = f(pending)
6+
loop(pending)
7+
}
8+
loop(null)
9+
}
10+
}

0 commit comments

Comments
 (0)