Skip to content

Commit e8e6a0a

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

File tree

3 files changed

+20
-15
lines changed

3 files changed

+20
-15
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
|}

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
}

0 commit comments

Comments
 (0)