Skip to content

Commit 2ce89da

Browse files
authored
Merge pull request #5751 from dotty-staging/fix-5750
Fix #5750: Type then part of If with no else part as Unit
2 parents e873908 + b6dc6bc commit 2ce89da

File tree

6 files changed

+52
-11
lines changed

6 files changed

+52
-11
lines changed

compiler/src/dotty/tools/dotc/ast/Positioned.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ abstract class Positioned(implicit @constructorOnly src: SourceFile) extends Pro
5353
if (mySpan.isSynthetic) {
5454
if (!mySpan.exists && span.exists) {
5555
envelope(source, span.startPos) // fill in children spans
56-
() // Note: the `()` is there to prevent some inefficient code from being generated.
57-
// Without it we get an allocation of a span here since the result type of the `if`
58-
// is `Any`, the lub of `Span` and `Unit`.
5956
}
6057
this
6158
}

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
261261
ctx.compilationUnit.source.exists &&
262262
sym != defn.SourceFileAnnot)
263263
sym.addAnnotation(Annotation.makeSourceFile(ctx.compilationUnit.source.file.path))
264-
tree
265264
}
266265
processMemberDef(super.transform(tree))
267266
case tree: New if isCheckable(tree) =>

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -728,12 +728,17 @@ 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-
val thenp2 :: elsep2 :: Nil = harmonic(harmonize, pt) {
732-
val thenp1 = typed(tree.thenp, pt.notApplied)
733-
val elsep1 = typed(tree.elsep.orElse(untpd.unitLiteral.withSpan(tree.span)), pt.notApplied)
734-
thenp1 :: elsep1 :: Nil
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)
735741
}
736-
assignType(cpy.If(tree)(cond1, thenp2, elsep2), thenp2, elsep2)
737742
}
738743

739744
/** Decompose function prototype into a list of parameter prototypes and a result prototype

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ class TestBCode extends DottyBytecodeTest {
568568

569569
/* Test that objects compile to *final* classes. */
570570

571-
def checkFinalClass(outputClassName: String, source: String) = {
571+
private def checkFinalClass(outputClassName: String, source: String) = {
572572
checkBCode(source) {
573573
dir =>
574574
val moduleIn = dir.lookupName(outputClassName, directory = false)
@@ -623,4 +623,30 @@ class TestBCode extends DottyBytecodeTest {
623623
| }
624624
|}
625625
""".stripMargin)
626+
627+
@Test def i5750 = {
628+
val source =
629+
"""class Test {
630+
| def foo: String = ""
631+
| def test(cond: Boolean): Int = {
632+
| if (cond) foo
633+
| 1
634+
| }
635+
|}
636+
""".stripMargin
637+
638+
checkBCode(source) { dir =>
639+
val clsIn = dir.lookupName("Test.class", directory = false).input
640+
val clsNode = loadClassNode(clsIn)
641+
val method = getMethod(clsNode, "test")
642+
643+
val boxUnit = instructionsFromMethod(method).exists {
644+
case Field(Opcodes.GETSTATIC, "scala/runtime/BoxedUnit", _, _) =>
645+
true
646+
case _ =>
647+
false
648+
}
649+
assertFalse(boxUnit)
650+
}
651+
}
626652
}

library/src/scala/tasty/reflect/Printers.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,6 @@ trait Printers
12261226
printedPrefix |= printProtectedOrPrivate(vdef)
12271227
if (vdef.symbol.flags.is(Flags.Mutable)) this += highlightValDef("var ", color)
12281228
else if (printedPrefix || !vdef.symbol.flags.is(Flags.CaseAcessor)) this += highlightValDef("val ", color)
1229-
else this // val not explicitly needed
12301229
}
12311230
}
12321231
case _ =>

tests/pos/i5750.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Test {
2+
def foo: String = ""
3+
def test(cond: Boolean): Int = {
4+
if (cond) foo
5+
1
6+
}
7+
8+
def test2(cond: Boolean): Unit = {
9+
val x = if (cond) foo
10+
}
11+
12+
def test3(cond: Boolean): Unit = {
13+
val x: Unit = if (cond) foo
14+
}
15+
}

0 commit comments

Comments
 (0)