@@ -224,6 +224,22 @@ object CheckCaptures:
224
224
checkNotUniversal.traverse(tpe.widen)
225
225
end checkNotUniversalInUnboxedResult
226
226
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
+
227
243
class CheckCaptures extends Recheck , SymTransformer :
228
244
thisPhase =>
229
245
@@ -244,7 +260,7 @@ class CheckCaptures extends Recheck, SymTransformer:
244
260
245
261
val ccState1 = new CCState // Dotty problem: Rename to ccState ==> Crash in ExplicitOuter
246
262
247
- class CaptureChecker (ictx : Context ) extends Rechecker (ictx):
263
+ class CaptureChecker (ictx : Context ) extends Rechecker (ictx), CheckerAPI :
248
264
249
265
/** The current environment */
250
266
private val rootEnv : Env = inContext(ictx):
@@ -262,10 +278,6 @@ class CheckCaptures extends Recheck, SymTransformer:
262
278
*/
263
279
private val todoAtPostCheck = new mutable.ListBuffer [() => Unit ]
264
280
265
- override def keepType (tree : Tree ) =
266
- super .keepType(tree)
267
- || tree.isInstanceOf [Try ] // type of `try` needs tp be checked for * escapes
268
-
269
281
/** Instantiate capture set variables appearing contra-variantly to their
270
282
* upper approximation.
271
283
*/
@@ -287,8 +299,8 @@ class CheckCaptures extends Recheck, SymTransformer:
287
299
*/
288
300
private def interpolateVarsIn (tpt : Tree )(using Context ): Unit =
289
301
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)
292
304
for msg <- ccState.approxWarnings do
293
305
report.warning(msg, tpt.srcPos)
294
306
ccState.approxWarnings.clear()
@@ -503,11 +515,11 @@ class CheckCaptures extends Recheck, SymTransformer:
503
515
then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
504
516
else if arg.span.exists then (" " , arg.srcPos)
505
517
else (" " , fn.srcPos)
506
- disallowRootCapabilitiesIn(arg.knownType , NoSymbol ,
518
+ disallowRootCapabilitiesIn(arg.nuType , NoSymbol ,
507
519
i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
508
520
509
521
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)
511
523
end disallowCapInTypeArgs
512
524
513
525
override def recheckIdent (tree : Ident , pt : Type )(using Context ): Type =
@@ -788,8 +800,8 @@ class CheckCaptures extends Recheck, SymTransformer:
788
800
*/
789
801
def checkContains (tree : TypeApply )(using Context ): Unit = tree match
790
802
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
793
805
capt.println(i " check contains $cs , $ref" )
794
806
ref match
795
807
case ref : CaptureRef if ref.isTracked =>
@@ -871,7 +883,7 @@ class CheckCaptures extends Recheck, SymTransformer:
871
883
case _ =>
872
884
(sym, " " )
873
885
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)
875
887
checkInferredResult(super .recheckValDef(tree, sym), tree)
876
888
finally
877
889
if ! sym.is(Param ) then
@@ -1572,7 +1584,7 @@ class CheckCaptures extends Recheck, SymTransformer:
1572
1584
private val setup : SetupAPI = thisPhase.prev.asInstanceOf [Setup ]
1573
1585
1574
1586
override def checkUnit (unit : CompilationUnit )(using Context ): Unit =
1575
- setup.setupUnit(unit.tpdTree, completeDef )
1587
+ setup.setupUnit(unit.tpdTree, this )
1576
1588
collectCapturedMutVars.traverse(unit.tpdTree)
1577
1589
1578
1590
if ctx.settings.YccPrintSetup .value then
@@ -1715,7 +1727,7 @@ class CheckCaptures extends Recheck, SymTransformer:
1715
1727
traverseChildren(tp)
1716
1728
1717
1729
if tree.isInstanceOf [InferredTypeTree ] then
1718
- checker.traverse(tree.knownType )
1730
+ checker.traverse(tree.nuType )
1719
1731
end healTypeParam
1720
1732
1721
1733
/** Under the unsealed policy: Arrays are like vars, check that their element types
@@ -1755,10 +1767,10 @@ class CheckCaptures extends Recheck, SymTransformer:
1755
1767
check(tree)
1756
1768
def check (tree : Tree )(using Context ) = tree match
1757
1769
case TypeApply (fun, args) =>
1758
- fun.knownType .widen match
1770
+ fun.nuType .widen match
1759
1771
case tl : PolyType =>
1760
1772
val normArgs = args.lazyZip(tl.paramInfos).map: (arg, bounds) =>
1761
- arg.withType(arg.knownType .forceBoxStatus(
1773
+ arg.withType(arg.nuType .forceBoxStatus(
1762
1774
bounds.hi.isBoxedCapturing | bounds.lo.isBoxedCapturing))
1763
1775
checkBounds(normArgs, tl)
1764
1776
args.lazyZip(tl.paramNames).foreach(healTypeParam(_, _, fun.symbol))
@@ -1778,7 +1790,7 @@ class CheckCaptures extends Recheck, SymTransformer:
1778
1790
def traverse (t : Tree )(using Context ) = t match
1779
1791
case tree : InferredTypeTree =>
1780
1792
case tree : New =>
1781
- case tree : TypeTree => checkAppliedTypesIn(tree.withKnownType )
1793
+ case tree : TypeTree => checkAppliedTypesIn(tree.withType(tree.nuType) )
1782
1794
case _ => traverseChildren(t)
1783
1795
checkApplied.traverse(unit)
1784
1796
end postCheck
0 commit comments