From df755d8b86709f68968f64c266ac90dfe773f5dd Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 24 Jun 2017 12:30:08 +0200 Subject: [PATCH 1/2] Emit "pure expression does nothing in statement position" warning --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 5 ++++- .../test/dotty/tools/dotc/CompilationTests.scala | 1 + tests/neg/customArgs/pureStatement.scala | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/neg/customArgs/pureStatement.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 7623ed9bb634..4281e27a2897 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1707,7 +1707,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case Thicket(stats) :: rest => traverse(stats ++ rest) case stat :: rest => - buf += typed(stat)(ctx.exprContext(stat, exprOwner)) + val stat1 = typed(stat)(ctx.exprContext(stat, exprOwner)) + if ((ctx.owner.isType || rest.nonEmpty) && isPureExpr(stat1) && !ctx.isAfterTyper) + ctx.warning(em"a pure expression does nothing in statement position", stat1.pos) + buf += stat1 traverse(rest) case nil => buf.toList diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 71eb03af3f89..7c21ddffef4f 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -163,6 +163,7 @@ class CompilationTests extends ParallelTesting { compileFile("../tests/neg/customArgs/noimports2.scala", defaultOptions.and("-Yno-imports")) + compileFile("../tests/neg/customArgs/overloadsOnAbstractTypes.scala", allowDoubleBindings) + compileFile("../tests/neg/customArgs/xfatalWarnings.scala", defaultOptions.and("-Xfatal-warnings")) + + compileFile("../tests/neg/customArgs/pureStatement.scala", defaultOptions.and("-Xfatal-warnings")) + compileFile("../tests/neg/customArgs/phantom-overload.scala", allowDoubleBindings) + compileFile("../tests/neg/tailcall/t1672b.scala", defaultOptions) + compileFile("../tests/neg/tailcall/t3275.scala", defaultOptions) + diff --git a/tests/neg/customArgs/pureStatement.scala b/tests/neg/customArgs/pureStatement.scala new file mode 100644 index 000000000000..4311a7d58c91 --- /dev/null +++ b/tests/neg/customArgs/pureStatement.scala @@ -0,0 +1,14 @@ +class IOCapability + +object Test { + // Forgot to mark `ev` implicit! + def doSideEffects(x: Int)(ev: IOCapability) = { + println("x: " + x) + } + + implicit val cap: IOCapability = new IOCapability + + 2 // error: pure expression does nothing in statement position + + doSideEffects(1) // error: pure expression does nothing in statement position +} From 70eaa36e42627ce417057fdc49dbf9ea4563ee34 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 24 Jun 2017 13:33:47 +0200 Subject: [PATCH 2/2] Fix condition where to check for pure expressions --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 4 ++-- tests/neg/customArgs/pureStatement.scala | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 4281e27a2897..b30fda7dc1ed 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1708,8 +1708,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit traverse(stats ++ rest) case stat :: rest => val stat1 = typed(stat)(ctx.exprContext(stat, exprOwner)) - if ((ctx.owner.isType || rest.nonEmpty) && isPureExpr(stat1) && !ctx.isAfterTyper) - ctx.warning(em"a pure expression does nothing in statement position", stat1.pos) + if (!ctx.isAfterTyper && isPureExpr(stat1)) + ctx.warning(em"a pure expression does nothing in statement position", stat.pos) buf += stat1 traverse(rest) case nil => diff --git a/tests/neg/customArgs/pureStatement.scala b/tests/neg/customArgs/pureStatement.scala index 4311a7d58c91..ac1a2026aae1 100644 --- a/tests/neg/customArgs/pureStatement.scala +++ b/tests/neg/customArgs/pureStatement.scala @@ -1,6 +1,20 @@ class IOCapability object Test { + "" // error: pure expression does nothing in statement position + + locally { + "" // error: pure expression does nothing in statement position + + println("") + + 42 // error: pure expression does nothing in statement position + + ((x: Int) => println("hi")) // error: pure expression does nothing in statement position + + () + } + // Forgot to mark `ev` implicit! def doSideEffects(x: Int)(ev: IOCapability) = { println("x: " + x)