@@ -14,6 +14,7 @@ import transform.{PreRecheck, Recheck}, Recheck.*
1414import CaptureSet .{IdentityCaptRefMap , IdempotentCaptRefMap }
1515import Synthetics .isExcluded
1616import util .SimpleIdentitySet
17+ import util .chaining .*
1718import reporting .Message
1819import printing .{Printer , Texts }, Texts .{Text , Str }
1920import collection .mutable
@@ -132,7 +133,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
132133 def mappedInfo =
133134 if toBeUpdated.contains(sym)
134135 then symd.info // don't transform symbols that will anyway be updated
135- else Fresh .fromCap(transformExplicitType(symd.info, sym), sym)
136+ else Fresh .fromCap(transformExplicitType(symd.info, sym), sym).tap(addOwnerAsHidden(_, sym))
136137 if Synthetics .needsTransform(symd) then
137138 Synthetics .transform(symd, mappedInfo)
138139 else if isPreCC(sym) then
@@ -489,6 +490,22 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
489490 extension (sym : Symbol ) def nextInfo (using Context ): Type =
490491 atPhase(thisPhase.next)(sym.info)
491492
493+ private def addOwnerAsHidden (tp : Type , owner : Symbol )(using Context ): Unit =
494+ val ref = owner.termRef
495+ def add = new TypeTraverser :
496+ var reach = false
497+ def traverse (t : Type ): Unit = t match
498+ case Fresh (hidden) =>
499+ if reach then hidden.elems += ref.reach
500+ else if ref.isTracked then hidden.elems += ref
501+ case t @ CapturingType (_, _) if t.isBoxed && ! reach =>
502+ reach = true
503+ try traverseChildren(t) finally reach = false
504+ case _ =>
505+ traverseChildren(t)
506+ if ref.isTrackableRef then add.traverse(tp)
507+ end addOwnerAsHidden
508+
492509 /** A traverser that adds knownTypes and updates symbol infos */
493510 def setupTraverser (checker : CheckerAPI ) = new TreeTraverserWithPreciseImportContexts :
494511 import checker .*
@@ -503,15 +520,17 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
503520 var transformed =
504521 if tree.isInferred
505522 then transformInferredType(tree.tpe)
506- else transformExplicitType(tree.tpe, sym, tptToCheck = tree)
523+ else
524+ val transformed = transformExplicitType(tree.tpe, sym, tptToCheck = tree)
525+ if boxed then transformed
526+ else Fresh .fromCap(transformed, sym).tap(addOwnerAsHidden(_, sym))
507527 if boxed then transformed = box(transformed)
508528 if sym.is(Param ) && (transformed ne tree.tpe) then
509529 paramSigChange += tree
510530 tree.setNuType(
511531 if boxed then transformed
512532 else if sym.hasAnnotation(defn.UncheckedCapturesAnnot ) then makeUnchecked(transformed)
513- else if tree.isInferred then transformed
514- else Fresh .fromCap(transformed, sym))
533+ else transformed)
515534
516535 /** Transform the type of a val or var or the result type of a def */
517536 def transformResultType (tpt : TypeTree , sym : Symbol )(using Context ): Unit =
@@ -899,7 +918,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
899918 def apply (t : Type ) = t match
900919 case t @ CapturingType (parent, refs) =>
901920 val parent1 = this (parent)
902- if refs.isUniversal then t.derivedCapturingType(parent1, CaptureSet .Fluid )
921+ if refs.isUniversalOrFresh then t.derivedCapturingType(parent1, CaptureSet .Fluid )
903922 else t
904923 case _ => mapFollowingAliases(t)
905924
0 commit comments