@@ -224,6 +224,22 @@ object CheckCaptures:
224224 checkNotUniversal.traverse(tpe.widen)
225225 end checkNotUniversalInUnboxedResult
226226
227+ trait CheckerAPI :
228+ /** Complete symbol info of a val or a def */
229+ def completeDef (tree : ValOrDefDef , sym : Symbol )(using Context ): Type
230+
231+ extension [T <: Tree ](tree : T )
232+
233+ /** Set new type of the tree if none was installed yet. */
234+ def setNuType (tpe : Type ): Unit
235+
236+ /** The new type of the tree, or if none was installed, the original type */
237+ def nuType (using Context ): Type
238+
239+ /** Was a new type installed for this tree? */
240+ def hasNuType : Boolean
241+ end CheckerAPI
242+
227243class CheckCaptures extends Recheck , SymTransformer :
228244 thisPhase =>
229245
@@ -244,7 +260,7 @@ class CheckCaptures extends Recheck, SymTransformer:
244260
245261 val ccState1 = new CCState // Dotty problem: Rename to ccState ==> Crash in ExplicitOuter
246262
247- class CaptureChecker (ictx : Context ) extends Rechecker (ictx):
263+ class CaptureChecker (ictx : Context ) extends Rechecker (ictx), CheckerAPI :
248264
249265 /** The current environment */
250266 private val rootEnv : Env = inContext(ictx):
@@ -262,10 +278,6 @@ class CheckCaptures extends Recheck, SymTransformer:
262278 */
263279 private val todoAtPostCheck = new mutable.ListBuffer [() => Unit ]
264280
265- override def keepType (tree : Tree ) =
266- super .keepType(tree)
267- || tree.isInstanceOf [Try ] // type of `try` needs tp be checked for * escapes
268-
269281 /** Instantiate capture set variables appearing contra-variantly to their
270282 * upper approximation.
271283 */
@@ -287,8 +299,8 @@ class CheckCaptures extends Recheck, SymTransformer:
287299 */
288300 private def interpolateVarsIn (tpt : Tree )(using Context ): Unit =
289301 if tpt.isInstanceOf [InferredTypeTree ] then
290- interpolator().traverse(tpt.knownType )
291- .showing(i " solved vars in ${tpt.knownType }" , capt)
302+ interpolator().traverse(tpt.nuType )
303+ .showing(i " solved vars in ${tpt.nuType }" , capt)
292304 for msg <- ccState.approxWarnings do
293305 report.warning(msg, tpt.srcPos)
294306 ccState.approxWarnings.clear()
@@ -503,11 +515,11 @@ class CheckCaptures extends Recheck, SymTransformer:
503515 then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
504516 else if arg.span.exists then (" " , arg.srcPos)
505517 else (" " , fn.srcPos)
506- disallowRootCapabilitiesIn(arg.knownType , NoSymbol ,
518+ disallowRootCapabilitiesIn(arg.nuType , NoSymbol ,
507519 i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
508520
509521 val param = fn.symbol.paramNamed(pname)
510- if param.isUseParam then markFree(arg.knownType .deepCaptureSet, pos)
522+ if param.isUseParam then markFree(arg.nuType .deepCaptureSet, pos)
511523 end disallowCapInTypeArgs
512524
513525 override def recheckIdent (tree : Ident , pt : Type )(using Context ): Type =
@@ -788,8 +800,8 @@ class CheckCaptures extends Recheck, SymTransformer:
788800 */
789801 def checkContains (tree : TypeApply )(using Context ): Unit = tree match
790802 case ContainsImpl (csArg, refArg) =>
791- val cs = csArg.knownType .captureSet
792- val ref = refArg.knownType
803+ val cs = csArg.nuType .captureSet
804+ val ref = refArg.nuType
793805 capt.println(i " check contains $cs , $ref" )
794806 ref match
795807 case ref : CaptureRef if ref.isTracked =>
@@ -871,7 +883,7 @@ class CheckCaptures extends Recheck, SymTransformer:
871883 case _ =>
872884 (sym, " " )
873885 disallowRootCapabilitiesIn(
874- tree.tpt.knownType , carrier, i " Mutable $sym" , " have type" , addendum, sym.srcPos)
886+ tree.tpt.nuType , carrier, i " Mutable $sym" , " have type" , addendum, sym.srcPos)
875887 checkInferredResult(super .recheckValDef(tree, sym), tree)
876888 finally
877889 if ! sym.is(Param ) then
@@ -1572,7 +1584,7 @@ class CheckCaptures extends Recheck, SymTransformer:
15721584 private val setup : SetupAPI = thisPhase.prev.asInstanceOf [Setup ]
15731585
15741586 override def checkUnit (unit : CompilationUnit )(using Context ): Unit =
1575- setup.setupUnit(unit.tpdTree, completeDef )
1587+ setup.setupUnit(unit.tpdTree, this )
15761588 collectCapturedMutVars.traverse(unit.tpdTree)
15771589
15781590 if ctx.settings.YccPrintSetup .value then
@@ -1715,7 +1727,7 @@ class CheckCaptures extends Recheck, SymTransformer:
17151727 traverseChildren(tp)
17161728
17171729 if tree.isInstanceOf [InferredTypeTree ] then
1718- checker.traverse(tree.knownType )
1730+ checker.traverse(tree.nuType )
17191731 end healTypeParam
17201732
17211733 /** Under the unsealed policy: Arrays are like vars, check that their element types
@@ -1755,10 +1767,10 @@ class CheckCaptures extends Recheck, SymTransformer:
17551767 check(tree)
17561768 def check (tree : Tree )(using Context ) = tree match
17571769 case TypeApply (fun, args) =>
1758- fun.knownType .widen match
1770+ fun.nuType .widen match
17591771 case tl : PolyType =>
17601772 val normArgs = args.lazyZip(tl.paramInfos).map: (arg, bounds) =>
1761- arg.withType(arg.knownType .forceBoxStatus(
1773+ arg.withType(arg.nuType .forceBoxStatus(
17621774 bounds.hi.isBoxedCapturing | bounds.lo.isBoxedCapturing))
17631775 checkBounds(normArgs, tl)
17641776 args.lazyZip(tl.paramNames).foreach(healTypeParam(_, _, fun.symbol))
@@ -1778,7 +1790,7 @@ class CheckCaptures extends Recheck, SymTransformer:
17781790 def traverse (t : Tree )(using Context ) = t match
17791791 case tree : InferredTypeTree =>
17801792 case tree : New =>
1781- case tree : TypeTree => checkAppliedTypesIn(tree.withKnownType )
1793+ case tree : TypeTree => checkAppliedTypesIn(tree.withType(tree.nuType) )
17821794 case _ => traverseChildren(t)
17831795 checkApplied.traverse(unit)
17841796 end postCheck
0 commit comments