@@ -144,9 +144,25 @@ object Inliner:
144144 else Nil
145145 case _ => Nil
146146 val refinements = openOpaqueAliases(cls.givenSelfType)
147+
148+ // Map references from the proxied termRef to its recursive type
149+ def mapTermRefReferences (recType : RecType , refinedType : Type ) =
150+ new TypeMap {
151+ def apply (tp : Type ) = tp match
152+ case RefinedType (a : RefinedType , b, info) => RefinedType (apply(a), b, apply(info))
153+ case RefinedType (a, b, info) => RefinedType (a, b, apply(info))
154+ case TypeRef (prefix, des) => TypeRef (apply(prefix), des)
155+ case termRef : TermRef if termRef == ref => recType.recThis
156+ case _ => mapOver(tp)
157+ }.apply(refinedType)
147158 val refinedType = refinements.foldLeft(ref : Type ): (parent, refinement) =>
148159 RefinedType (parent, refinement._1, TypeAlias (refinement._2))
149- val refiningSym = newSym(InlineBinderName .fresh(), Synthetic , refinedType, span)
160+
161+ val recType = RecType .closeOver ( recType =>
162+ mapTermRefReferences(recType, refinedType)
163+ )
164+
165+ val refiningSym = newSym(InlineBinderName .fresh(), Synthetic , recType, span)
150166 refiningSym.termRef
151167
152168 def unapply (refiningRef : TermRef )(using Context ): Option [TermRef ] =
@@ -387,7 +403,9 @@ class Inliner(val call: tpd.Tree)(using Context):
387403 val refiningRef = OpaqueProxy (ref, cls, call.span)
388404 val refiningSym = refiningRef.symbol.asTerm
389405 val refinedType = refiningRef.info
390- val refiningDef = ValDef (refiningSym, tpd.ref(ref).cast(refinedType), inferred = true ).withSpan(span)
406+ val refiningDef = addProxiesForRecurrentOpaques(
407+ ValDef (refiningSym, tpd.ref(ref).cast(refinedType), inferred = true ).withSpan(span)
408+ )
391409 inlining.println(i " add opaque alias proxy $refiningDef for $ref in $tp" )
392410 bindingsBuf += refiningDef
393411 opaqueProxies += ((ref, refiningSym.termRef))
@@ -407,6 +425,29 @@ class Inliner(val call: tpd.Tree)(using Context):
407425 }
408426 )
409427
428+ /** Transforms proxies that reference other opaque types, like for:
429+ * object Obj1 { opaque type A = Int }
430+ * object Obj2 { opaque type B = A }
431+ * and proxy$1 of type Obj2.type{type B = Obj2.A }
432+ * creates proxy$2 of type Obj1.type{type A = Int }
433+ * and transforms proxy$1 into Obj2.type{type B = proxy$2.A }
434+ */
435+ private def addProxiesForRecurrentOpaques (binding : ValDef )(using Context ): ValDef =
436+ def fixRefinedTypes (ref : Type ): Unit =
437+ ref match
438+ case recType : RecType => fixRefinedTypes(recType.underlying)
439+ case RefinedType (parent : RefinedType , name, info) =>
440+ addOpaqueProxies(info.widen, binding.span, true )
441+ fixRefinedTypes(parent)
442+ case RefinedType (parent, name, info) =>
443+ addOpaqueProxies(info.widen, binding.span, true )
444+ case _ =>
445+ fixRefinedTypes(binding.symbol.info)
446+ binding.symbol.info = mapOpaques.typeMap(binding.symbol.info)
447+ mapOpaques.transform(binding).asInstanceOf [ValDef ]
448+ .showing(i " transformed this binding exposing opaque aliases: $result" , inlining)
449+ end addProxiesForRecurrentOpaques
450+
410451 /** If `binding` contains TermRefs that refer to objects with opaque
411452 * type aliases, add proxy definitions that expose these aliases
412453 * and substitute such TermRefs with theproxies. Example from pos/opaque-inline1.scala:
0 commit comments