@@ -38,7 +38,8 @@ import annotation.tailrec
3838import Implicits ._
3939import util .Stats .record
4040import config .Printers .{gadts , typr , debug }
41- import config .Feature ._
41+ import config .Feature
42+ import config .Feature .{sourceVersion , migrateTo3 }
4243import config .SourceVersion ._
4344import rewrites .Rewrites .patch
4445import NavigateAST ._
@@ -695,7 +696,7 @@ class Typer extends Namer
695696 case Whole (16 ) => // cant parse hex literal as double
696697 case _ => return lit(doubleFromDigits(digits))
697698 }
698- else if genericNumberLiteralsEnabled
699+ else if Feature .enabled( Feature .genericNumberLiterals)
699700 && target.isValueType && isFullyDefined(target, ForceDegree .none)
700701 then
701702 // If expected type is defined with a FromDigits instance, use that one
@@ -1711,10 +1712,30 @@ class Typer extends Namer
17111712 .withNotNullInfo(body1.notNullInfo.retractedInfo.seq(cond1.notNullInfoIf(false )))
17121713 }
17131714
1715+ /** Add givens reflecting `CanThrow` capabilities for all checked exceptions matched
1716+ * by `cases`. The givens appear in nested blocks with earlier cases leading to
1717+ * more deeply nested givens. This way, given priority will be the same as pattern priority.
1718+ * The functionality is enabled if the experimental.saferExceptions language feature is enabled.
1719+ */
1720+ def addCanThrowCapabilities (expr : untpd.Tree , cases : List [CaseDef ])(using Context ): untpd.Tree =
1721+ def makeCanThrow (tp : Type ): untpd.Tree =
1722+ untpd.ValDef (
1723+ EvidenceParamName .fresh(),
1724+ untpd.TypeTree (defn.CanThrowClass .typeRef.appliedTo(tp)),
1725+ untpd.ref(defn.Predef_undefined ))
1726+ .withFlags(Given | Final | Lazy | Erased )
1727+ .withSpan(expr.span)
1728+ val caps =
1729+ for
1730+ CaseDef (pat, _, _) <- cases
1731+ if Feature .enabled(Feature .saferExceptions) && pat.tpe.widen.isCheckedException
1732+ yield makeCanThrow(pat.tpe.widen)
1733+ caps.foldLeft(expr)((e, g) => untpd.Block (g :: Nil , e))
1734+
17141735 def typedTry (tree : untpd.Try , pt : Type )(using Context ): Try = {
17151736 val expr2 :: cases2x = harmonic(harmonize, pt) {
1716- val expr1 = typed(tree.expr, pt.dropIfProto)
17171737 val cases1 = typedCases(tree.cases, EmptyTree , defn.ThrowableType , pt.dropIfProto)
1738+ val expr1 = typed(addCanThrowCapabilities(tree.expr, cases1), pt.dropIfProto)
17181739 expr1 :: cases1
17191740 }
17201741 val finalizer1 = typed(tree.finalizer, defn.UnitType )
@@ -1733,6 +1754,7 @@ class Typer extends Namer
17331754
17341755 def typedThrow (tree : untpd.Throw )(using Context ): Tree = {
17351756 val expr1 = typed(tree.expr, defn.ThrowableType )
1757+ checkCanThrow(expr1.tpe.widen, tree.span)
17361758 Throw (expr1).withSpan(tree.span)
17371759 }
17381760
@@ -1828,7 +1850,7 @@ class Typer extends Namer
18281850 def typedAppliedTypeTree (tree : untpd.AppliedTypeTree )(using Context ): Tree = {
18291851 tree.args match
18301852 case arg :: _ if arg.isTerm =>
1831- if dependentEnabled then
1853+ if Feature . dependentEnabled then
18321854 return errorTree(tree, i " Not yet implemented: T(...) " )
18331855 else
18341856 return errorTree(tree, dependentStr)
@@ -1925,7 +1947,7 @@ class Typer extends Namer
19251947 typeIndexedLambdaTypeTree(tree, tparams, body)
19261948
19271949 def typedTermLambdaTypeTree (tree : untpd.TermLambdaTypeTree )(using Context ): Tree =
1928- if dependentEnabled then
1950+ if Feature . dependentEnabled then
19291951 errorTree(tree, i " Not yet implemented: (...) =>> ... " )
19301952 else
19311953 errorTree(tree, dependentStr)
@@ -2303,7 +2325,7 @@ class Typer extends Namer
23032325 ctx.phase.isTyper &&
23042326 cdef1.symbol.ne(defn.DynamicClass ) &&
23052327 cdef1.tpe.derivesFrom(defn.DynamicClass ) &&
2306- ! dynamicsEnabled
2328+ ! Feature . dynamicsEnabled
23072329 if (reportDynamicInheritance) {
23082330 val isRequired = parents1.exists(_.tpe.isRef(defn.DynamicClass ))
23092331 report.featureWarning(nme.dynamics.toString, " extension of type scala.Dynamic" , cls, isRequired, cdef.srcPos)
@@ -3216,7 +3238,7 @@ class Typer extends Namer
32163238 case args =>
32173239 args.lengthCompare(1 ) > 0
32183240 && isUnary(funType)
3219- && autoTuplingEnabled
3241+ && Feature . autoTuplingEnabled
32203242
32213243 def adaptToArgs (wtp : Type , pt : FunProto ): Tree = wtp match {
32223244 case wtp : MethodOrPoly =>
@@ -3424,7 +3446,7 @@ class Typer extends Namer
34243446 def isAutoApplied (sym : Symbol ): Boolean =
34253447 sym.isConstructor
34263448 || sym.matchNullaryLoosely
3427- || warnOnMigration(MissingEmptyArgumentList (sym.show), tree.srcPos)
3449+ || Feature . warnOnMigration(MissingEmptyArgumentList (sym.show), tree.srcPos)
34283450 && { patch(tree.span.endPos, " ()" ); true }
34293451
34303452 // Reasons NOT to eta expand:
@@ -3755,7 +3777,7 @@ class Typer extends Namer
37553777 case ref : TermRef =>
37563778 pt match {
37573779 case pt : FunProto
3758- if needsTupledDual(ref, pt) && autoTuplingEnabled =>
3780+ if needsTupledDual(ref, pt) && Feature . autoTuplingEnabled =>
37593781 adapt(tree, pt.tupledDual, locked)
37603782 case _ =>
37613783 adaptOverloaded(ref)
0 commit comments