@@ -3,18 +3,16 @@ package transform
3
3
4
4
import ast .{TreeTypeMap , tpd }
5
5
import config .Printers .tailrec
6
- import core .Contexts ._
7
- import core .Constants .Constant
8
- import core .Flags ._
9
- import core .NameKinds .{TailLabelName , TailLocalName , TailTempName }
10
- import core .StdNames .nme
11
- import core .Symbols ._
12
- import reporting ._
6
+ import core .*
7
+ import Contexts .* , Flags .* , Symbols .*
8
+ import Constants .Constant
9
+ import NameKinds .{TailLabelName , TailLocalName , TailTempName }
10
+ import StdNames .nme
11
+ import reporting .*
13
12
import transform .MegaPhase .MiniPhase
14
13
import util .LinearSet
15
14
import dotty .tools .uncheckedNN
16
15
17
-
18
16
/** A Tail Rec Transformer.
19
17
*
20
18
* What it does:
@@ -161,15 +159,26 @@ class TailRec extends MiniPhase {
161
159
val rhsFullyTransformed = varForRewrittenThis match {
162
160
case Some (localThisSym) =>
163
161
val thisRef = localThisSym.termRef
164
- new TreeTypeMap (
162
+ val substitute = new TreeTypeMap (
165
163
typeMap = _.substThisUnlessStatic(enclosingClass, thisRef)
166
164
.subst(rewrittenParamSyms, varsForRewrittenParamSyms.map(_.termRef)),
167
165
treeMap = {
168
166
case tree : This if tree.symbol == enclosingClass => Ident (thisRef)
169
167
case tree => tree
170
168
}
171
- ).transform(rhsSemiTransformed)
172
-
169
+ )
170
+ // The previous map will map `This` references to `Ident`s even under `Super`.
171
+ // This violates super's contract. We fix this by cleaning up `Ident`s under
172
+ // super, mapping them back to the original `This` reference. This is not
173
+ // very elegant, but I did not manage to find a cleaner way to handle this.
174
+ // See pos/tailrec-super.scala for a test case.
175
+ val cleanup = new TreeMap :
176
+ override def transform (t : Tree )(using Context ) = t match
177
+ case Super (qual : Ident , mix) if ! qual.tpe.isInstanceOf [Types .ThisType ] =>
178
+ cpy.Super (t)(This (enclosingClass), mix)
179
+ case _ =>
180
+ super .transform(t)
181
+ cleanup.transform(substitute.transform(rhsSemiTransformed))
173
182
case none =>
174
183
new TreeTypeMap (
175
184
typeMap = _.subst(rewrittenParamSyms, varsForRewrittenParamSyms.map(_.termRef))
0 commit comments