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