diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index f426aa1562ad..e35b0c9bba68 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2064,9 +2064,7 @@ class Typer extends Namer traverse(stats ++ rest) case stat :: rest => val stat1 = typed(stat)(ctx.exprContext(stat, exprOwner)) - if (!ctx.isAfterTyper && isPureExpr(stat1) && - !stat1.tpe.isRef(defn.UnitClass) && !isSelfOrSuperConstrCall(stat1)) - ctx.warning(PureExpressionInStatementPosition(stat, exprOwner), stat.pos) + checkStatementPurity(stat1)(stat, exprOwner) buf += stat1 traverse(rest) case nil => @@ -2607,10 +2605,13 @@ class Typer extends Namer val folded = ConstFold(tree, pt) if (folded ne tree) return adaptConstant(folded, folded.tpe.asInstanceOf[ConstantType]) // drop type if prototype is Unit - if (pt isRef defn.UnitClass) + if (pt isRef defn.UnitClass) { // local adaptation makes sure every adapted tree conforms to its pt // so will take the code path that decides on inlining - return tpd.Block(adapt(tree, WildcardType, locked) :: Nil, Literal(Constant(()))) + val tree1 = adapt(tree, WildcardType, locked) + checkStatementPurity(tree1)(tree, ctx.owner) + return tpd.Block(tree1 :: Nil, Literal(Constant(()))) + } // convert function literal to SAM closure tree match { case closure(Nil, id @ Ident(nme.ANON_FUN), _) @@ -2770,4 +2771,9 @@ class Typer extends Namer case _ => } } + + private def checkStatementPurity(tree: tpd.Tree)(original: untpd.Tree, exprOwner: Symbol)(implicit ctx: Context): Unit = { + if (!ctx.isAfterTyper && isPureExpr(tree) && !tree.tpe.isRef(defn.UnitClass) && !isSelfOrSuperConstrCall(tree)) + ctx.warning(PureExpressionInStatementPosition(original, exprOwner), original.pos) + } } diff --git a/compiler/src/dotty/tools/io/ZipArchive.scala b/compiler/src/dotty/tools/io/ZipArchive.scala index 668a2aab8886..fa27ac4245cf 100644 --- a/compiler/src/dotty/tools/io/ZipArchive.scala +++ b/compiler/src/dotty/tools/io/ZipArchive.scala @@ -157,8 +157,7 @@ final class FileZipArchive(jpath: JPath) extends ZipArchive(jpath) { while (entries.hasMoreElements) { val zipEntry = entries.nextElement val dir = getDir(dirs, zipEntry) - if (zipEntry.isDirectory) dir - else { + if (!zipEntry.isDirectory) { val f = if (ZipArchive.closeZipFile) new LazyEntry( diff --git a/tests/neg-custom-args/fatal-warnings/i5013.scala b/tests/neg-custom-args/fatal-warnings/i5013.scala new file mode 100644 index 000000000000..3581810259e9 --- /dev/null +++ b/tests/neg-custom-args/fatal-warnings/i5013.scala @@ -0,0 +1,9 @@ +class Foo { + + def foo1: Unit = 2 // error: A pure expression does nothing in statement position + + def foo2: Unit = { + 3 // error: A pure expression does nothing in statement position + 4 // error: A pure expression does nothing in statement position + } +} diff --git a/tests/neg-custom-args/fatal-warnings/i5013b.scala b/tests/neg-custom-args/fatal-warnings/i5013b.scala new file mode 100644 index 000000000000..309c153e2ea3 --- /dev/null +++ b/tests/neg-custom-args/fatal-warnings/i5013b.scala @@ -0,0 +1,16 @@ +class Foo { + + val a: Int = 3 + + def b: 1 = { + println("1") + 1 + } + + val c: Unit = () + + def foo1: Unit = a // error: A pure expression does nothing in statement position + def foo2: Unit = b + def foo3: Unit = c // Not addapted to { c; () } and hence c is not a statement + +} diff --git a/tests/patmat/i4226.scala b/tests/patmat/i4226.scala index ad75c4d1236c..5d3e587939b6 100644 --- a/tests/patmat/i4226.scala +++ b/tests/patmat/i4226.scala @@ -9,7 +9,7 @@ object Empty { object Test { val a: Maybe[Int] = Just(2) def main(args: Array[String]): Unit = a match { - case Just(2) => true + case Just(2) => case Empty() => } } diff --git a/tests/patmat/i4226b.scala b/tests/patmat/i4226b.scala index d489b1d5b8f0..9549804575fc 100644 --- a/tests/patmat/i4226b.scala +++ b/tests/patmat/i4226b.scala @@ -9,7 +9,7 @@ object Empty { object Test { val a: Maybe[Int] = Just(2) def main(args: Array[String]): Unit = a match { - case Just(2) => true + case Just(2) => case Empty() => } }