@@ -3,18 +3,16 @@ package transform
33
44import ast .{TreeTypeMap , tpd }
55import 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 .*
1312import transform .MegaPhase .MiniPhase
1413import util .LinearSet
1514import dotty .tools .uncheckedNN
1615
17-
1816/** A Tail Rec Transformer.
1917 *
2018 * What it does:
@@ -161,15 +159,26 @@ class TailRec extends MiniPhase {
161159 val rhsFullyTransformed = varForRewrittenThis match {
162160 case Some (localThisSym) =>
163161 val thisRef = localThisSym.termRef
164- new TreeTypeMap (
162+ val substitute = new TreeTypeMap (
165163 typeMap = _.substThisUnlessStatic(enclosingClass, thisRef)
166164 .subst(rewrittenParamSyms, varsForRewrittenParamSyms.map(_.termRef)),
167165 treeMap = {
168166 case tree : This if tree.symbol == enclosingClass => Ident (thisRef)
169167 case tree => tree
170168 }
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))
173182 case none =>
174183 new TreeTypeMap (
175184 typeMap = _.subst(rewrittenParamSyms, varsForRewrittenParamSyms.map(_.termRef))
0 commit comments