@@ -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,26 @@ 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 (guardOK, canReduceGuard) =
1451
+ if cdef.guard.isEmpty then (true , true )
1452
+ else typer.typed(cdef.guard.subst(from, to), defn.BooleanType ) match {
1453
+ case ConstantValue (v : Boolean ) => (v, true )
1454
+ case _ => (false , false )
1449
1455
}
1450
- }
1451
- if (guardOK) Some ((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to)))
1452
- else None
1456
+ if guardOK then Some ((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to), canReduceGuard))
1457
+ else if canReduceGuard then None
1458
+ else Some ((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to), canReduceGuard))
1453
1459
}
1454
1460
else None
1455
1461
}
1456
1462
1457
1463
def recur (cases : List [CaseDef ]): MatchRedux = cases match {
1458
1464
case Nil => None
1459
- case cdef :: cases1 => reduceCase(cdef) `orElse` recur(cases1)
1465
+ case cdef :: cases1 =>
1466
+ reduceCase(cdef) match
1467
+ case None => recur(cases1)
1468
+ case r @ Some ((caseBindings, rhs, canReduceGuard)) if canReduceGuard => Some ((caseBindings, rhs))
1469
+ case _ => None
1460
1470
}
1461
1471
1462
1472
recur(cases)
0 commit comments