Skip to content

Commit 6d9b0f1

Browse files
authored
Fix stack overflow errors when generating opaque type proxies (#22479)
Before the regressive PR, we would check via the generated opaqueProxies list whether one was already generated. In that PR, we tried allowing generating proxies for rhs of currently generated proxy. Since we have to add the generated proxy to opaqueProxies only after that step, this could cause infinite recursion (and adding the proxies earlier could cause another infinite loop). To fix that, we add another collection for termrefs which we already visited this way, but which is not used in the `mapOpaques` function.
1 parent 4ab5c5d commit 6d9b0f1

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/inlines/Inliner.scala

+5-1
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ class Inliner(val call: tpd.Tree)(using Context):
384384
*/
385385
private val opaqueProxies = new mutable.ListBuffer[(TermRef, TermRef)]
386386

387+
/** TermRefs for which we already started synthesising proxies */
388+
private val visitedTermRefs = new mutable.HashSet[TermRef]
389+
387390
protected def hasOpaqueProxies = opaqueProxies.nonEmpty
388391

389392
/** Map first halves of opaqueProxies pairs to second halves, using =:= as equality */
@@ -401,8 +404,9 @@ class Inliner(val call: tpd.Tree)(using Context):
401404
for cls <- ref.widen.baseClasses do
402405
if cls.containsOpaques
403406
&& (forThisProxy || inlinedMethod.isContainedIn(cls))
404-
&& mapRef(ref).isEmpty
407+
&& !visitedTermRefs.contains(ref)
405408
then
409+
visitedTermRefs += ref
406410
val refiningRef = OpaqueProxy(ref, cls, call.span)
407411
val refiningSym = refiningRef.symbol.asTerm
408412
val refinedType = refiningRef.info

Diff for: tests/pos/i22468.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Result.*
2+
opaque type Result[+E, +A] = Success[A] | Error[E]
3+
4+
object Result:
5+
opaque type Success[+A] = A
6+
sealed abstract class Error[+E]
7+
8+
extension [E, A](self: Result[E, A])
9+
inline def transform[B]: B = ???
10+
def problem: Boolean = transform[Boolean]

0 commit comments

Comments
 (0)