@@ -223,6 +223,22 @@ object CheckCaptures:
223223 checkNotUniversal.traverse(tpe.widen)
224224 end checkNotUniversalInUnboxedResult
225225
226+ trait CheckerAPI :
227+ /** Complete symbol info of a val or a def */
228+ def completeDef (tree : ValOrDefDef , sym : Symbol )(using Context ): Type
229+
230+ extension [T <: Tree ](tree : T )
231+
232+ /** Set new type of the tree if none was installed yet. */
233+ def setNuType (tpe : Type ): Unit
234+
235+ /** The new type of the tree, or if none was installed, the original type */
236+ def nuType (using Context ): Type
237+
238+ /** Was a new type installed for this tree? */
239+ def hasNuType : Boolean
240+ end CheckerAPI
241+
226242class CheckCaptures extends Recheck , SymTransformer :
227243 thisPhase =>
228244
@@ -243,7 +259,7 @@ class CheckCaptures extends Recheck, SymTransformer:
243259
244260 val ccState1 = new CCState // Dotty problem: Rename to ccState ==> Crash in ExplicitOuter
245261
246- class CaptureChecker (ictx : Context ) extends Rechecker (ictx):
262+ class CaptureChecker (ictx : Context ) extends Rechecker (ictx), CheckerAPI :
247263
248264 /** The current environment */
249265 private val rootEnv : Env = inContext(ictx):
@@ -261,10 +277,6 @@ class CheckCaptures extends Recheck, SymTransformer:
261277 */
262278 private val todoAtPostCheck = new mutable.ListBuffer [() => Unit ]
263279
264- override def keepType (tree : Tree ) =
265- super .keepType(tree)
266- || tree.isInstanceOf [Try ] // type of `try` needs tp be checked for * escapes
267-
268280 /** Instantiate capture set variables appearing contra-variantly to their
269281 * upper approximation.
270282 */
@@ -286,8 +298,8 @@ class CheckCaptures extends Recheck, SymTransformer:
286298 */
287299 private def interpolateVarsIn (tpt : Tree )(using Context ): Unit =
288300 if tpt.isInstanceOf [InferredTypeTree ] then
289- interpolator().traverse(tpt.knownType )
290- .showing(i " solved vars in ${tpt.knownType }" , capt)
301+ interpolator().traverse(tpt.nuType )
302+ .showing(i " solved vars in ${tpt.nuType }" , capt)
291303 for msg <- ccState.approxWarnings do
292304 report.warning(msg, tpt.srcPos)
293305 ccState.approxWarnings.clear()
@@ -501,11 +513,11 @@ class CheckCaptures extends Recheck, SymTransformer:
501513 then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
502514 else if arg.span.exists then (" " , arg.srcPos)
503515 else (" " , fn.srcPos)
504- disallowRootCapabilitiesIn(arg.knownType , NoSymbol ,
516+ disallowRootCapabilitiesIn(arg.nuType , NoSymbol ,
505517 i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
506518
507519 val param = fn.symbol.paramNamed(pname)
508- if param.isUseParam then markFree(arg.knownType .deepCaptureSet, pos)
520+ if param.isUseParam then markFree(arg.nuType .deepCaptureSet, pos)
509521 end disallowCapInTypeArgs
510522
511523 override def recheckIdent (tree : Ident , pt : Type )(using Context ): Type =
@@ -769,8 +781,8 @@ class CheckCaptures extends Recheck, SymTransformer:
769781 */
770782 def checkContains (tree : TypeApply )(using Context ): Unit = tree match
771783 case ContainsImpl (csArg, refArg) =>
772- val cs = csArg.knownType .captureSet
773- val ref = refArg.knownType
784+ val cs = csArg.nuType .captureSet
785+ val ref = refArg.nuType
774786 capt.println(i " check contains $cs , $ref" )
775787 ref match
776788 case ref : CaptureRef if ref.isTracked =>
@@ -852,7 +864,7 @@ class CheckCaptures extends Recheck, SymTransformer:
852864 case _ =>
853865 (sym, " " )
854866 disallowRootCapabilitiesIn(
855- tree.tpt.knownType , carrier, i " Mutable $sym" , " have type" , addendum, sym.srcPos)
867+ tree.tpt.nuType , carrier, i " Mutable $sym" , " have type" , addendum, sym.srcPos)
856868 checkInferredResult(super .recheckValDef(tree, sym), tree)
857869 finally
858870 if ! sym.is(Param ) then
@@ -1533,7 +1545,7 @@ class CheckCaptures extends Recheck, SymTransformer:
15331545 private val setup : SetupAPI = thisPhase.prev.asInstanceOf [Setup ]
15341546
15351547 override def checkUnit (unit : CompilationUnit )(using Context ): Unit =
1536- setup.setupUnit(unit.tpdTree, completeDef )
1548+ setup.setupUnit(unit.tpdTree, this )
15371549 collectCapturedMutVars.traverse(unit.tpdTree)
15381550
15391551 if ctx.settings.YccPrintSetup .value then
@@ -1676,7 +1688,7 @@ class CheckCaptures extends Recheck, SymTransformer:
16761688 traverseChildren(tp)
16771689
16781690 if tree.isInstanceOf [InferredTypeTree ] then
1679- checker.traverse(tree.knownType )
1691+ checker.traverse(tree.nuType )
16801692 end healTypeParam
16811693
16821694 /** Under the unsealed policy: Arrays are like vars, check that their element types
@@ -1716,10 +1728,10 @@ class CheckCaptures extends Recheck, SymTransformer:
17161728 check(tree)
17171729 def check (tree : Tree )(using Context ) = tree match
17181730 case TypeApply (fun, args) =>
1719- fun.knownType .widen match
1731+ fun.nuType .widen match
17201732 case tl : PolyType =>
17211733 val normArgs = args.lazyZip(tl.paramInfos).map: (arg, bounds) =>
1722- arg.withType(arg.knownType .forceBoxStatus(
1734+ arg.withType(arg.nuType .forceBoxStatus(
17231735 bounds.hi.isBoxedCapturing | bounds.lo.isBoxedCapturing))
17241736 checkBounds(normArgs, tl)
17251737 args.lazyZip(tl.paramNames).foreach(healTypeParam(_, _, fun.symbol))
@@ -1739,7 +1751,7 @@ class CheckCaptures extends Recheck, SymTransformer:
17391751 def traverse (t : Tree )(using Context ) = t match
17401752 case tree : InferredTypeTree =>
17411753 case tree : New =>
1742- case tree : TypeTree => checkAppliedTypesIn(tree.withKnownType )
1754+ case tree : TypeTree => checkAppliedTypesIn(tree.withType(tree.nuType) )
17431755 case _ => traverseChildren(t)
17441756 checkApplied.traverse(unit)
17451757 end postCheck
0 commit comments