Skip to content

Commit 9242e95

Browse files
committed
Type If and Match in statement position as Unit
This is an alternative fix for #5750
1 parent 1947222 commit 9242e95

File tree

9 files changed

+35
-30
lines changed

9 files changed

+35
-30
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -728,17 +728,11 @@ class Typer extends Namer
728728
def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context): Tree = track("typedIf") {
729729
if (tree.isInline) checkInInlineContext("inline if", tree.posd)
730730
val cond1 = typed(tree.cond, defn.BooleanType)
731-
732-
if (tree.elsep.isEmpty) {
733-
val thenp1 = typed(tree.thenp, defn.UnitType)
734-
val elsep1 = tpd.unitLiteral.withSpan(tree.span.endPos)
735-
cpy.If(tree)(cond1, thenp1, elsep1).withType(defn.UnitType)
736-
}
737-
else {
738-
val thenp1 :: elsep1 :: Nil = harmonic(harmonize, pt)(
739-
(tree.thenp :: tree.elsep :: Nil).map(typed(_, pt.notApplied)))
740-
assignType(cpy.If(tree)(cond1, thenp1, elsep1), thenp1, elsep1)
731+
val thenp1 :: elsep1 :: Nil = harmonic(harmonize, pt) {
732+
val elsep = tree.elsep.orElse(untpd.unitLiteral.withSpan(tree.span.endPos))
733+
(tree.thenp :: elsep :: Nil).map(typed(_, pt.notApplied))
741734
}
735+
assignType(cpy.If(tree)(cond1, thenp1, elsep1), thenp1, elsep1)
742736
}
743737

744738
/** Decompose function prototype into a list of parameter prototypes and a result prototype
@@ -2089,7 +2083,15 @@ class Typer extends Namer
20892083
case Thicket(stats) :: rest =>
20902084
traverse(stats ++ rest)
20912085
case stat :: rest =>
2092-
val stat1 = typed(stat)(ctx.exprContext(stat, exprOwner))
2086+
val pt = stat match {
2087+
case _: untpd.If | _: untpd.Match =>
2088+
// Typing `if` and `match` statement with `Unit` as expected
2089+
// type produces more efficient code (see #5750).
2090+
defn.UnitType
2091+
case _ =>
2092+
WildcardType
2093+
}
2094+
val stat1 = typed(stat, pt)(ctx.exprContext(stat, exprOwner))
20932095
checkStatementPurity(stat1)(stat, exprOwner)
20942096
buf += stat1
20952097
traverse(rest)

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,12 @@ class TestBCode extends DottyBytecodeTest {
627627
@Test def i5750 = {
628628
val source =
629629
"""class Test {
630-
| def foo: String = ""
630+
| def foo(): String = ""
631631
| def test(cond: Boolean): Int = {
632-
| if (cond) foo
632+
| if (cond) foo()
633+
| if (cond) () else foo()
634+
| if (cond) foo() else ()
635+
| cond match { case true => foo(); case _ => () }
633636
| 1
634637
| }
635638
|}

compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,7 @@ class ErrorMessagesTests extends ErrorMessagesTest {
13671367
| val z = Boo(1, "foo")
13681368
|
13691369
| z match {
1370-
| case Boo(a, b, c) => a
1370+
| case Boo(a, b, c) => ()
13711371
| }
13721372
|}
13731373
""".stripMargin

tests/patmat/enum/patmat-enum.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ object Test1 {
22
val day: Day = ???
33

44
day match {
5-
case Day.MONDAY => true
6-
case Day.TUESDAY => true
7-
case Day.WEDNESDAY => true
5+
case Day.MONDAY => ()
6+
case Day.TUESDAY => ()
7+
case Day.WEDNESDAY => ()
88
}
99
}
1010

@@ -13,9 +13,9 @@ object Test2 {
1313
val day: Day = ???
1414

1515
day match {
16-
case MONDAY => true
17-
case TUESDAY => true
18-
case WEDNESDAY => true
19-
case SUNDAY => true
16+
case MONDAY => ()
17+
case TUESDAY => ()
18+
case WEDNESDAY => ()
19+
case SUNDAY => ()
2020
}
2121
}

tests/patmat/t3111.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ object Test {
22
val bool: Boolean = false
33

44
bool match {
5-
case true => "true!"
5+
case true => ()
66
}
77

88
bool match {
9-
case true => "true!"
10-
case false => "false!"
11-
case _ => "cats and dogs living together... mass hysteria!"
9+
case true => ()
10+
case false => ()
11+
case _ => ()
1212
}
1313
}

tests/patmat/tuple.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
object Test {
22
(4, (4, 6)) match {
3-
case (x, (y, z)) => true
3+
case (x, (y, z)) => ()
44
}
55
}

tests/pos-special/isInstanceOf/3324d.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class Test {
22
val x: Any = ???
33

44
x match {
5-
case _: List[Int @unchecked] => 5
6-
case _: Option[Int] @unchecked => 5
5+
case _: List[Int @unchecked] => ()
6+
case _: Option[Int] @unchecked => ()
77
}
88
}

tests/run/virtpatmat_alts.decompiled

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
object Test extends dotty.runtime.LegacyApp() {
33
scala.Tuple2.apply[scala.Boolean, scala.Boolean](true, true) match {
44
case (scala.Tuple2(true, true) | scala.Tuple2(false, false)) =>
5-
1
5+
()
66
}
77
scala.List.apply[scala.Int](5) match {
88
case (scala.::(1, scala.Nil) | scala.::(2, scala.Nil)) =>

tests/run/virtpatmat_alts.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44
object Test extends dotty.runtime.LegacyApp {
55
(true, true) match {
6-
case (true, true) | (false, false) => 1
6+
case (true, true) | (false, false) => ()
77
}
88

99
List(5) match {

0 commit comments

Comments
 (0)