Skip to content

Commit 352317c

Browse files
Handle inlining of matches with sub cases
A sub match is inline iff the outer match is
1 parent e26be67 commit 352317c

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

compiler/src/dotty/tools/dotc/inlines/InlineReducer.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,13 @@ class InlineReducer(inliner: Inliner)(using Context):
394394
case ConstantValue(v: Boolean) => (v, true)
395395
case _ => (false, false)
396396
}
397-
if guardOK then Some((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to), canReduceGuard))
398-
else if canReduceGuard then None
399-
else Some((caseBindings.map(_.subst(from, to)), cdef.body.subst(from, to), canReduceGuard))
397+
if !canReduceGuard then Some((List.empty, EmptyTree, false))
398+
else if !guardOK then None
399+
else cdef.body.subst(from, to) match
400+
case t: SubMatch => // a sub match of an inline match is also inlined
401+
reduceInlineMatch(t.selector, t.selector.tpe, t.cases, typer).map:
402+
(subCaseBindings, rhs) => (caseBindings.map(_.subst(from, to)) ++ subCaseBindings, rhs, true)
403+
case b => Some((caseBindings.map(_.subst(from, to)), b, true))
400404
}
401405
else None
402406
}

tests/pos/inline-sub-match.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import scala.language.experimental.matchWithSubCases
2+
3+
object Test:
4+
5+
// using transparent to test whether test whether reduced as expected
6+
transparent inline def foo(i: Int, j: Int): String =
7+
inline i match
8+
case 0 with j match
9+
case 1 => "01"
10+
case 2 => "02"
11+
case 1 with j match
12+
case 1 => "11"
13+
case 2 => "12"
14+
case _ => "3"
15+
16+
val r01: "01" = foo(0, 1)
17+
val r02: "02" = foo(0, 2)
18+
val r11: "11" = foo(1, 1)
19+
val r31: "3" = foo(3, 1)
20+
21+
transparent inline def bar(x: Option[Any]): String =
22+
inline x match
23+
case Some(y: Int) with y match
24+
case 1 => "a"
25+
case 2 => "b"
26+
case Some(z: String) => "c"
27+
case _ => "d"
28+
29+
val x = bar(Some(2)) // FIX this reduces to "c", but this appears to be a more general issue than sub-matches
30+
val y = bar(Some("hello"))

0 commit comments

Comments
 (0)