Skip to content

Commit 0c66517

Browse files
author
Aggelos Biboudis
authored
Merge pull request #5707 from dotty-staging/fix-#5013
Fix #5013: Check statement purity for adapted expressions of Unit
2 parents 9333e77 + c29a531 commit 0c66517

File tree

6 files changed

+39
-9
lines changed

6 files changed

+39
-9
lines changed

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,9 +2064,7 @@ class Typer extends Namer
20642064
traverse(stats ++ rest)
20652065
case stat :: rest =>
20662066
val stat1 = typed(stat)(ctx.exprContext(stat, exprOwner))
2067-
if (!ctx.isAfterTyper && isPureExpr(stat1) &&
2068-
!stat1.tpe.isRef(defn.UnitClass) && !isSelfOrSuperConstrCall(stat1))
2069-
ctx.warning(PureExpressionInStatementPosition(stat, exprOwner), stat.pos)
2067+
checkStatementPurity(stat1)(stat, exprOwner)
20702068
buf += stat1
20712069
traverse(rest)
20722070
case nil =>
@@ -2607,10 +2605,13 @@ class Typer extends Namer
26072605
val folded = ConstFold(tree, pt)
26082606
if (folded ne tree) return adaptConstant(folded, folded.tpe.asInstanceOf[ConstantType])
26092607
// drop type if prototype is Unit
2610-
if (pt isRef defn.UnitClass)
2608+
if (pt isRef defn.UnitClass) {
26112609
// local adaptation makes sure every adapted tree conforms to its pt
26122610
// so will take the code path that decides on inlining
2613-
return tpd.Block(adapt(tree, WildcardType, locked) :: Nil, Literal(Constant(())))
2611+
val tree1 = adapt(tree, WildcardType, locked)
2612+
checkStatementPurity(tree1)(tree, ctx.owner)
2613+
return tpd.Block(tree1 :: Nil, Literal(Constant(())))
2614+
}
26142615
// convert function literal to SAM closure
26152616
tree match {
26162617
case closure(Nil, id @ Ident(nme.ANON_FUN), _)
@@ -2770,4 +2771,9 @@ class Typer extends Namer
27702771
case _ =>
27712772
}
27722773
}
2774+
2775+
private def checkStatementPurity(tree: tpd.Tree)(original: untpd.Tree, exprOwner: Symbol)(implicit ctx: Context): Unit = {
2776+
if (!ctx.isAfterTyper && isPureExpr(tree) && !tree.tpe.isRef(defn.UnitClass) && !isSelfOrSuperConstrCall(tree))
2777+
ctx.warning(PureExpressionInStatementPosition(original, exprOwner), original.pos)
2778+
}
27732779
}

compiler/src/dotty/tools/io/ZipArchive.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,7 @@ final class FileZipArchive(jpath: JPath) extends ZipArchive(jpath) {
157157
while (entries.hasMoreElements) {
158158
val zipEntry = entries.nextElement
159159
val dir = getDir(dirs, zipEntry)
160-
if (zipEntry.isDirectory) dir
161-
else {
160+
if (!zipEntry.isDirectory) {
162161
val f =
163162
if (ZipArchive.closeZipFile)
164163
new LazyEntry(
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Foo {
2+
3+
def foo1: Unit = 2 // error: A pure expression does nothing in statement position
4+
5+
def foo2: Unit = {
6+
3 // error: A pure expression does nothing in statement position
7+
4 // error: A pure expression does nothing in statement position
8+
}
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Foo {
2+
3+
val a: Int = 3
4+
5+
def b: 1 = {
6+
println("1")
7+
1
8+
}
9+
10+
val c: Unit = ()
11+
12+
def foo1: Unit = a // error: A pure expression does nothing in statement position
13+
def foo2: Unit = b
14+
def foo3: Unit = c // Not addapted to { c; () } and hence c is not a statement
15+
16+
}

tests/patmat/i4226.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ object Empty {
99
object Test {
1010
val a: Maybe[Int] = Just(2)
1111
def main(args: Array[String]): Unit = a match {
12-
case Just(2) => true
12+
case Just(2) =>
1313
case Empty() =>
1414
}
1515
}

tests/patmat/i4226b.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ object Empty {
99
object Test {
1010
val a: Maybe[Int] = Just(2)
1111
def main(args: Array[String]): Unit = a match {
12-
case Just(2) => true
12+
case Just(2) =>
1313
case Empty() =>
1414
}
1515
}

0 commit comments

Comments
 (0)