Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b6dc6bc

Browse files
Fix #5750: Type then part of If with no else part as Unit
1 parent e873908 commit b6dc6bc

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+
privatedef 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)

AltStyle によって変換されたページ (->オリジナル) /