@@ -2452,20 +2452,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
24522452 * │ Finally ├──────┐ │ Finally ├──┐
24532453 * └────┬────┘ │ └────┬────┘ │
24542454 * ▼ └─────────┴───────┴─►
2455- * α = tryEffect
2456- * λ = α.retracted.seq.(catchEffects.reduce.alt)
2457- * β = α.alt(λ)
2458- * finallyCtx = β.retracted
2459- * δ = finallyEffect
2460- * resultNNInfo = β.seq(δ).alt(β.retracted.seq(δ).seq(empty.terminated))
2455+ * exprNNInfo = Effect of the try block if completed normally
2456+ * casesNNInfo = Effect of catch blocks completing normally
2457+ * normalAfterCasesInfo = Exceptional try followed by normal catches
2458+ * We type finalizer with normalAfterCasesInfo.retracted
24612459 *
2462- * It is sufficient to type finally once provided that we type it in a context
2463- * that considers all the paths before it that reach the finally. Since the NNinfo
2464- * that we get from typing finally summarizes the effect of the finally, we can
2465- * type the finally once and use the obtained NN info twice: once sequenced
2466- * with β (normalNNInfo) and once sequenced with β.retractedInfo but post-sequenced
2467- * by empty.terminated (to indicate that this path does not reach the code after
2468- * the try-catch-finally).
2460+ * Overall effect of try-catch-finally =
2461+ * resNNInfo =
2462+ * (exprNNInfo OR normalAfterCasesInfo) followed by normal finally block
2463+ *
2464+ * For all nninfo, if a tree can be typed using nninfo.retractedInfo, then it can
2465+ * also be typed using nninfo.
24692466 */
24702467 def typedTry (tree : untpd.Try , pt : Type )(using Context ): Try =
24712468 val expr2 :: cases2x = harmonic(harmonize, pt) {
@@ -2486,20 +2483,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
24862483 }: @ unchecked
24872484 val cases2 = cases2x.asInstanceOf [List [CaseDef ]]
24882485 val exprNNInfo = expr2.notNullInfo
2486+ val casesNNInfo =
2487+ cases2.map(_.notNullInfo)
2488+ .foldLeft(NotNullInfo .empty.terminatedInfo)(_.alt(_))
2489+ val normalAfterCasesInfo = exprNNInfo.retractedInfo.seq(casesNNInfo)
2490+
24892491 // It is possible to have non-exhaustive cases, and some exceptions are thrown and not caught.
24902492 // Therefore, the code in the finalizer and after the try block can only rely on the retracted
24912493 // info from the cases' body.
2492- val casesNNInfo = if cases2.nonEmpty then
2493- exprNNInfo.retractedInfo.seq(cases2.map(_.notNullInfo).reduce(_.alt(_)))
2494- else
2495- NotNullInfo .empty.terminatedInfo
2496- val catchSuccessNNInfo = exprNNInfo.alt(casesNNInfo)
2497- val catchFailNNInfo = catchSuccessNNInfo.retractedInfo
2498-
2499- val finalizer1 = typed(tree.finalizer, defn.UnitType )(using ctx.addNotNullInfo(catchFailNNInfo))
2500- val normalFinalNNInfo = catchSuccessNNInfo.seq(finalizer1.notNullInfo)
2501- val exceptionalFinalNNInfo = catchFailNNInfo.seq(finalizer1.notNullInfo)
2502- val resNNInfo = normalFinalNNInfo.alt(exceptionalFinalNNInfo.seq(NotNullInfo .empty.terminatedInfo))
2494+ val finalizer1 = typed(tree.finalizer, defn.UnitType )(using ctx.addNotNullInfo(normalAfterCasesInfo.retractedInfo))
2495+ val resNNInfo = exprNNInfo.alt(normalAfterCasesInfo).seq(finalizer1.notNullInfo)
25032496 assignType(cpy.Try (tree)(expr2, cases2, finalizer1), expr2, cases2).withNotNullInfo(resNNInfo)
25042497
25052498 def typedTry (tree : untpd.ParsedTry , pt : Type )(using Context ): Try =
0 commit comments