@@ -1242,6 +1242,11 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1242
1242
*/
1243
1243
type MatchRedux = Option [(List [MemberDef ], Tree )]
1244
1244
1245
+ /** Same as MatchRedux, but also includes a boolean
1246
+ * that is true if the guard can be checked at compile time.
1247
+ */
1248
+ type MatchReduxWithGuard = Option [(List [MemberDef ], Tree , Boolean )]
1249
+
1245
1250
/** Reduce an inline match
1246
1251
* @param mtch the match tree
1247
1252
* @param scrutinee the scrutinee expression, assumed to be pure, or
@@ -1423,7 +1428,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1423
1428
val scrutineeSym = newSym(InlineScrutineeName .fresh(), Synthetic , scrutType).asTerm
1424
1429
val scrutineeBinding = normalizeBinding(ValDef (scrutineeSym, scrutinee))
1425
1430
1426
- def reduceCase (cdef : CaseDef ): MatchRedux = {
1431
+ def reduceCase (cdef : CaseDef ): MatchReduxWithGuard = {
1427
1432
val caseBindingMap = new mutable.ListBuffer [(Symbol , MemberDef )]()
1428
1433
1429
1434
def substBindings (
@@ -1442,21 +1447,27 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1442
1447
val gadtCtx = ctx.fresh.setFreshGADTBounds.addMode(Mode .GadtConstraintInference )
1443
1448
if (reducePattern(caseBindingMap, scrutineeSym.termRef, cdef.pat)(using gadtCtx)) {
1444
1449
val (caseBindings, from, to) = substBindings(caseBindingMap.toList, mutable.ListBuffer (), Nil , Nil )
1445
- val guardOK = cdef.guard.isEmpty || {
1446
- typer.typed(cdef.guard.subst(from, to), defn.BooleanType ) match {
1447
- case ConstantValue (true ) => true
1448
- case _ => false
1450
+ val typedGuard = typer.typed(cdef.guard.subst(from, to), defn.BooleanType )
1451
+ val (guardOK, canReduceGuard) =
1452
+ if cdef.guard.isEmpty then (true , true )
1453
+ else typer.typed(cdef.guard.subst(from, to), defn.BooleanType ) match {
1454
+ case ConstantValue (v : Boolean ) => (v, true )
1455
+ case _ => (false , false )
1449
1456
}
1450
- }
1451
- if (guardOK) Some ((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to)))
1452
- else None
1457
+ if guardOK then Some ((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to), canReduceGuard))
1458
+ else if canReduceGuard then None
1459
+ else Some ((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to), canReduceGuard))
1453
1460
}
1454
1461
else None
1455
1462
}
1456
1463
1457
1464
def recur (cases : List [CaseDef ]): MatchRedux = cases match {
1458
1465
case Nil => None
1459
- case cdef :: cases1 => reduceCase(cdef) `orElse` recur(cases1)
1466
+ case cdef :: cases1 =>
1467
+ reduceCase(cdef) match
1468
+ case None => recur(cases1)
1469
+ case r @ Some ((caseBindings, rhs, canReduceGuard)) if canReduceGuard => Some ((caseBindings, rhs))
1470
+ case _ => None
1460
1471
}
1461
1472
1462
1473
recur(cases)
0 commit comments