diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 03d33f330927..15ccea63c5dc 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -728,17 +728,11 @@ class Typer extends Namer def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context): Tree = track("typedIf") { if (tree.isInline) checkInInlineContext("inline if", tree.posd) val cond1 = typed(tree.cond, defn.BooleanType) - - if (tree.elsep.isEmpty) { - val thenp1 = typed(tree.thenp, defn.UnitType) - val elsep1 = tpd.unitLiteral.withSpan(tree.span.endPos) - cpy.If(tree)(cond1, thenp1, elsep1).withType(defn.UnitType) - } - else { - val thenp1 :: elsep1 :: Nil = harmonic(harmonize, pt)( - (tree.thenp :: tree.elsep :: Nil).map(typed(_, pt.notApplied))) - assignType(cpy.If(tree)(cond1, thenp1, elsep1), thenp1, elsep1) + val thenp1 :: elsep1 :: Nil = harmonic(harmonize, pt) { + val elsep = tree.elsep.orElse(untpd.unitLiteral.withSpan(tree.span.endPos)) + (tree.thenp :: elsep :: Nil).map(typed(_, pt.notApplied)) } + assignType(cpy.If(tree)(cond1, thenp1, elsep1), thenp1, elsep1) } /** Decompose function prototype into a list of parameter prototypes and a result prototype @@ -2089,7 +2083,15 @@ class Typer extends Namer case Thicket(stats) :: rest => traverse(stats ++ rest) case stat :: rest => - val stat1 = typed(stat)(ctx.exprContext(stat, exprOwner)) + val pt = stat match { + case _: untpd.If | _: untpd.Match => + // Typing `if` and `match` statement with `Unit` as expected + // type produces more efficient code (see #5750). + defn.UnitType + case _ => + WildcardType + } + val stat1 = typed(stat, pt)(ctx.exprContext(stat, exprOwner)) checkStatementPurity(stat1)(stat, exprOwner) buf += stat1 traverse(rest) diff --git a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala index 75c90fe36a0d..040286dc5809 100644 --- a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala +++ b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala @@ -627,9 +627,12 @@ class TestBCode extends DottyBytecodeTest { @Test def i5750 = { val source = """class Test { - | def foo: String = "" + | def foo(): String = "" | def test(cond: Boolean): Int = { - | if (cond) foo + | if (cond) foo() + | if (cond) () else foo() + | if (cond) foo() else () + | cond match { case true => foo(); case _ => () } | 1 | } |} diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 394afa7a90d9..8271004910c6 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1367,7 +1367,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { | val z = Boo(1, "foo") | | z match { - | case Boo(a, b, c) => a + | case Boo(a, b, c) => () | } |} """.stripMargin diff --git a/tests/patmat/enum/patmat-enum.scala b/tests/patmat/enum/patmat-enum.scala index ec5c90255f7a..f489147222e1 100644 --- a/tests/patmat/enum/patmat-enum.scala +++ b/tests/patmat/enum/patmat-enum.scala @@ -2,9 +2,9 @@ object Test1 { val day: Day = ??? day match { - case Day.MONDAY => true - case Day.TUESDAY => true - case Day.WEDNESDAY => true + case Day.MONDAY => () + case Day.TUESDAY => () + case Day.WEDNESDAY => () } } @@ -13,9 +13,9 @@ object Test2 { val day: Day = ??? day match { - case MONDAY => true - case TUESDAY => true - case WEDNESDAY => true - case SUNDAY => true + case MONDAY => () + case TUESDAY => () + case WEDNESDAY => () + case SUNDAY => () } } \ No newline at end of file diff --git a/tests/patmat/t3111.scala b/tests/patmat/t3111.scala index 8f2bc5a273a9..c7aee2cc3c26 100644 --- a/tests/patmat/t3111.scala +++ b/tests/patmat/t3111.scala @@ -2,12 +2,12 @@ object Test { val bool: Boolean = false bool match { - case true => "true!" + case true => () } bool match { - case true => "true!" - case false => "false!" - case _ => "cats and dogs living together... mass hysteria!" + case true => () + case false => () + case _ => () } } \ No newline at end of file diff --git a/tests/patmat/tuple.scala b/tests/patmat/tuple.scala index f33a5cfec38f..4ef8fa4526a8 100644 --- a/tests/patmat/tuple.scala +++ b/tests/patmat/tuple.scala @@ -1,5 +1,5 @@ object Test { (4, (4, 6)) match { - case (x, (y, z)) => true + case (x, (y, z)) => () } } \ No newline at end of file diff --git a/tests/pos-special/isInstanceOf/3324d.scala b/tests/pos-special/isInstanceOf/3324d.scala index d39ebe80c465..0277e2ef7ee7 100644 --- a/tests/pos-special/isInstanceOf/3324d.scala +++ b/tests/pos-special/isInstanceOf/3324d.scala @@ -2,7 +2,7 @@ class Test { val x: Any = ??? x match { - case _: List[Int @unchecked] => 5 - case _: Option[Int] @unchecked => 5 + case _: List[Int @unchecked] => () + case _: Option[Int] @unchecked => () } } \ No newline at end of file diff --git a/tests/run/virtpatmat_alts.decompiled b/tests/run/virtpatmat_alts.decompiled index 2e60b123fb46..3ff59132608e 100644 --- a/tests/run/virtpatmat_alts.decompiled +++ b/tests/run/virtpatmat_alts.decompiled @@ -2,7 +2,7 @@ object Test extends dotty.runtime.LegacyApp() { scala.Tuple2.apply[scala.Boolean, scala.Boolean](true, true) match { case (scala.Tuple2(true, true) | scala.Tuple2(false, false)) => - 1 + () } scala.List.apply[scala.Int](5) match { case (scala.::(1, scala.Nil) | scala.::(2, scala.Nil)) => diff --git a/tests/run/virtpatmat_alts.scala b/tests/run/virtpatmat_alts.scala index d76b29307d5b..2ea9a51d66df 100644 --- a/tests/run/virtpatmat_alts.scala +++ b/tests/run/virtpatmat_alts.scala @@ -3,7 +3,7 @@ */ object Test extends dotty.runtime.LegacyApp { (true, true) match { - case (true, true) | (false, false) => 1 + case (true, true) | (false, false) => () } List(5) match {