@@ -21,6 +21,7 @@ import CCState.*
21
21
import dotty .tools .dotc .util .NoSourcePosition
22
22
import CheckCaptures .CheckerAPI
23
23
import NamerOps .methodType
24
+ import NameKinds .{CanThrowEvidenceName , TryOwnerName }
24
25
25
26
/** Operations accessed from CheckCaptures */
26
27
trait SetupAPI :
@@ -51,6 +52,15 @@ object Setup:
51
52
Some ((res, exc))
52
53
case _ =>
53
54
None
55
+
56
+ def firstCanThrowEvidence (body : Tree )(using Context ): Option [Tree ] = body match
57
+ case Block (stats, expr) =>
58
+ if stats.isEmpty then firstCanThrowEvidence(expr)
59
+ else stats.find:
60
+ case vd : ValDef => vd.symbol.name.is(CanThrowEvidenceName )
61
+ case _ => false
62
+ case _ => None
63
+
54
64
end Setup
55
65
import Setup .*
56
66
@@ -480,9 +490,9 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
480
490
end transformExplicitType
481
491
482
492
/** Update info of `sym` for CheckCaptures phase only */
483
- private def updateInfo (sym : Symbol , info : Type )(using Context ) =
493
+ private def updateInfo (sym : Symbol , info : Type , owner : Symbol )(using Context ) =
484
494
toBeUpdated += sym
485
- sym.updateInfo(thisPhase, info, newFlagsFor(sym))
495
+ sym.updateInfo(thisPhase, info, newFlagsFor(sym), owner )
486
496
toBeUpdated -= sym
487
497
488
498
/** The info of `sym` at the CheckCaptures phase */
@@ -590,6 +600,17 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
590
600
traverse(elems)
591
601
tpt.setNuType(box(transformInferredType(tpt.tpe)))
592
602
603
+ case tree @ Try (body, catches, finalizer) =>
604
+ val tryOwner = firstCanThrowEvidence(body) match
605
+ case Some (vd) =>
606
+ newSymbol(ctx.owner, TryOwnerName .fresh(),
607
+ Method | Synthetic , ExprType (defn.NothingType ), coord = tree.span)
608
+ case _ =>
609
+ ctx.owner
610
+ inContext(ctx.withOwner(tryOwner)):
611
+ traverse(body)
612
+ catches.foreach(traverse)
613
+ traverse(finalizer)
593
614
case _ =>
594
615
traverseChildren(tree)
595
616
postProcess(tree)
@@ -634,6 +655,8 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
634
655
// have a new type installed here (meaning hasRememberedType is true)
635
656
def signatureChanges =
636
657
tree.tpt.hasNuType || paramSignatureChanges
658
+ def ownerChanges =
659
+ ctx.owner.name.is(TryOwnerName )
637
660
638
661
def paramsToCap (mt : Type )(using Context ): Type = mt match
639
662
case mt : MethodType =>
@@ -644,38 +667,40 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
644
667
mt.derivedLambdaType(resType = paramsToCap(mt.resType))
645
668
case _ => mt
646
669
647
- // If there's a change in the signature, update the info of `sym`
648
- if sym.exists && signatureChanges then
670
+ // If there's a change in the signature or owner , update the info of `sym`
671
+ if sym.exists && ( signatureChanges || ownerChanges) then
649
672
val updatedInfo =
650
-
651
- val paramSymss = sym.paramSymss
652
- def newInfo (using Context ) = // will be run in this or next phase
653
- root.toResultInResults(sym, report.error(_, tree.srcPos)):
654
- if sym.is(Method ) then
655
- paramsToCap(methodType(paramSymss, localReturnType))
656
- else tree.tpt.nuType
657
- if tree.tpt.isInstanceOf [InferredTypeTree ]
658
- && ! sym.is(Param ) && ! sym.is(ParamAccessor )
659
- then
660
- val prevInfo = sym.info
661
- new LazyType :
662
- def complete (denot : SymDenotation )(using Context ) =
663
- assert(ctx.phase == thisPhase.next, i " $sym" )
664
- sym.info = prevInfo // set info provisionally so we can analyze the symbol in recheck
665
- completeDef(tree, sym, this )
666
- sym.info = newInfo
667
- .showing(i " new info of $sym = $result" , capt)
668
- else if sym.is(Method ) then
669
- new LazyType :
670
- def complete (denot : SymDenotation )(using Context ) =
671
- sym.info = newInfo
672
- .showing(i " new info of $sym = $result" , capt)
673
- else newInfo
674
- updateInfo(sym, updatedInfo)
673
+ if signatureChanges then
674
+ val paramSymss = sym.paramSymss
675
+ def newInfo (using Context ) = // will be run in this or next phase
676
+ root.toResultInResults(sym, report.error(_, tree.srcPos)):
677
+ if sym.is(Method ) then
678
+ paramsToCap(methodType(paramSymss, localReturnType))
679
+ else tree.tpt.nuType
680
+ if tree.tpt.isInstanceOf [InferredTypeTree ]
681
+ && ! sym.is(Param ) && ! sym.is(ParamAccessor )
682
+ then
683
+ val prevInfo = sym.info
684
+ new LazyType :
685
+ def complete (denot : SymDenotation )(using Context ) =
686
+ assert(ctx.phase == thisPhase.next, i " $sym" )
687
+ sym.info = prevInfo // set info provisionally so we can analyze the symbol in recheck
688
+ completeDef(tree, sym, this )
689
+ sym.info = newInfo
690
+ .showing(i " new info of $sym = $result" , capt)
691
+ else if sym.is(Method ) then
692
+ new LazyType :
693
+ def complete (denot : SymDenotation )(using Context ) =
694
+ sym.info = newInfo
695
+ .showing(i " new info of $sym = $result" , capt)
696
+ else newInfo
697
+ else sym.info
698
+ val updatedOwner = if ownerChanges then ctx.owner else sym.owner
699
+ updateInfo(sym, updatedInfo, updatedOwner)
675
700
676
701
case tree : Bind =>
677
702
val sym = tree.symbol
678
- updateInfo(sym, transformInferredType(sym.info))
703
+ updateInfo(sym, transformInferredType(sym.info), sym.owner )
679
704
case tree : TypeDef =>
680
705
tree.symbol match
681
706
case cls : ClassSymbol =>
@@ -708,7 +733,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
708
733
// Install new types and if it is a module class also update module object
709
734
if (selfInfo1 ne selfInfo) || (ps1 ne ps) then
710
735
val newInfo = ClassInfo (prefix, cls, ps1, decls, selfInfo1)
711
- updateInfo(cls, newInfo)
736
+ updateInfo(cls, newInfo, cls.owner )
712
737
capt.println(i " update class info of $cls with parents $ps selfinfo $selfInfo to $newInfo" )
713
738
cls.thisType.asInstanceOf [ThisType ].invalidateCaches()
714
739
if cls.is(ModuleClass ) then
@@ -721,7 +746,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
721
746
// This would potentially give stackoverflows when setup is run repeatedly.
722
747
// One test case is pos-custom-args/captures/checkbounds.scala under
723
748
// ccConfig.alwaysRepeatRun = true.
724
- updateInfo(modul, CapturingType (modul.info, selfCaptures))
749
+ updateInfo(modul, CapturingType (modul.info, selfCaptures), modul.owner )
725
750
modul.termRef.invalidateCaches()
726
751
case _ =>
727
752
case _ =>
0 commit comments