From 2daadc5d1a31d4ba556da91f23b9b8b2fb6856da Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 16 May 2024 21:06:44 -0700 Subject: [PATCH] Defer warn value discard to refchecks --- .../tools/nsc/typechecker/RefChecks.scala | 36 ++++++++++++------- .../scala/tools/nsc/typechecker/Typers.scala | 2 +- .../reflect/internal/StdAttachments.scala | 7 +++- .../reflect/runtime/JavaUniverseForce.scala | 2 ++ test/async/jvm/toughtype.check | 5 +-- test/files/neg/discard-advice-a.check | 12 +++++++ test/files/neg/discard-advice-a.scala | 13 +++++++ test/files/neg/discard-advice-b.check | 9 +++++ test/files/neg/discard-advice-b.scala | 13 +++++++ test/files/neg/discard-advice-c.check | 6 ++++ test/files/neg/discard-advice-c.scala | 13 +++++++ test/files/neg/discard-advice-d.check | 15 ++++++++ test/files/neg/discard-advice-d.scala | 13 +++++++ test/files/neg/nonunit-if.check | 8 +---- test/files/neg/t11379a.check | 19 ---------- test/files/neg/t11379a2.check | 21 +++++++++++ test/files/neg/t11379a2.scala | 23 ++++++++++++ test/files/neg/t12495.check | 6 ++-- test/files/neg/t9847.check | 23 ++++-------- test/files/run/contrib674.check | 5 +-- test/files/run/names-defaults.check | 5 +-- test/files/run/patmatnew.check | 10 ++---- test/files/run/repl-paste-error.check | 6 +--- test/files/run/t3488.check | 14 -------- test/files/run/t3488.scala | 8 +++-- 25 files changed, 192 insertions(+), 102 deletions(-) create mode 100644 test/files/neg/discard-advice-a.check create mode 100644 test/files/neg/discard-advice-a.scala create mode 100644 test/files/neg/discard-advice-b.check create mode 100644 test/files/neg/discard-advice-b.scala create mode 100644 test/files/neg/discard-advice-c.check create mode 100644 test/files/neg/discard-advice-c.scala create mode 100644 test/files/neg/discard-advice-d.check create mode 100644 test/files/neg/discard-advice-d.scala create mode 100644 test/files/neg/t11379a2.check create mode 100644 test/files/neg/t11379a2.scala delete mode 100644 test/files/run/t3488.check diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 6c19b197963b..b5655377127c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1908,6 +1908,13 @@ abstract class RefChecks extends Transform { && !treeInfo.hasExplicitUnit(t) // suppressed by explicit expr: Unit && !isJavaApplication(t) // Java methods are inherently side-effecting ) + def checkDiscardValue(t: Tree): Boolean = + t.hasAttachment[DiscardedValue.type] && { + t.removeAttachment[DiscardedValue.type] + val msg = s"discarded non-Unit value of type ${t.tpe}" + refchecksWarning(t.pos, msg, WarningCategory.WFlagValueDiscard) + true + } // begin checkInterestingResultInStatement settings.warnNonUnitStatement.value && checkInterestingShapes(t) && { val where = t match { @@ -1922,7 +1929,7 @@ abstract class RefChecks extends Transform { def msg = s"unused value of type ${where.tpe}" refchecksWarning(where.pos, msg, WarningCategory.OtherPureStatement) true - } + } || checkDiscardValue(t) } // end checkInterestingResultInStatement override def transform(tree: Tree): Tree = { @@ -2038,27 +2045,30 @@ abstract class RefChecks extends Transform { case blk @ Block(stats, expr) => // diagnostic info - val (count, result0, adapted) = + val (count, result0) = expr match { - case Block(expr :: Nil, Literal(Constant(()))) => (1, expr, true) - case Literal(Constant(())) => (0, EmptyTree, false) - case _ => (1, EmptyTree, false) + case Block(expr :: Nil, Literal(Constant(()))) => (1, expr) + case Literal(Constant(())) => (0, EmptyTree) + case _ => (1, EmptyTree) } val isMultiline = stats.lengthCompare(1 - count) > 0 - def checkPure(t: Tree, supple: Boolean): Unit = + def checkPure(t: Tree): Unit = if (!treeInfo.hasExplicitUnit(t) && treeInfo.isPureExprForWarningPurposes(t)) { - val msg = "a pure expression does nothing in statement position" - val parens = if (isMultiline) "multiline expressions might require enclosing parentheses" else "" - val discard = if (adapted) "; a value can be silently discarded when Unit is expected" else "" + val msg = + if (t.hasAttachment[DiscardedExpr.type]) { + t.removeAttachment[DiscardedExpr.type] + "discarded pure expression does nothing" + } + else "a pure expression does nothing in statement position" val text = - if (supple) s"$parens$discard" - else if (!parens.isEmpty) s"$msg; $parens" else msg + if (!isMultiline) msg + else s"$msg; multiline expressions might require enclosing parentheses" refchecksWarning(t.pos, text, WarningCategory.OtherPureStatement) } // check block for unintended "expression in statement position" - stats.foreach { t => if (!checkInterestingResultInStatement(t)) checkPure(t, supple = false) } - if (result0.nonEmpty) checkPure(result0, supple = true) + stats.foreach { t => if (!checkInterestingResultInStatement(t)) checkPure(t) } + if (result0.nonEmpty) result0.updateAttachment(DiscardedExpr) // see checkPure on recursion into result def checkImplicitlyAdaptedBlockResult(t: Tree): Unit = expr match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index e4e8128cb369..18eaafd6c7ca 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1170,7 +1170,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper @inline def warnValueDiscard(): Unit = if (!isPastTyper && settings.warnValueDiscard.value && !treeInfo.isThisTypeResult(tree) && !treeInfo.hasExplicitUnit(tree)) - context.warning(tree.pos, s"discarded non-Unit value of type ${tree.tpe}", WarningCategory.WFlagValueDiscard) + tree.updateAttachment(DiscardedValue) @inline def warnNumericWiden(tpSym: Symbol, ptSym: Symbol): Unit = if (!isPastTyper) { val targetIsWide = ptSym == FloatClass || ptSym == DoubleClass val isInharmonic = { diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index 6cee9a135dd4..06f650f496fb 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -160,7 +160,7 @@ trait StdAttachments { case object RootSelection extends PlainAttachment /** Marks a Typed tree with Unit tpt. */ - case object TypedExpectingUnitAttachment + case object TypedExpectingUnitAttachment extends PlainAttachment def explicitlyUnit(tree: Tree): Boolean = tree.hasAttachment[TypedExpectingUnitAttachment.type] /** For `val i = 42`, marks field as inferred so accessor (getter) can warn if implicit. */ @@ -176,4 +176,9 @@ trait StdAttachments { /** Not a named arg in an application. Used for suspicious literal booleans. */ case object UnnamedArg extends PlainAttachment + + /** Adapted under value discard at typer. */ + case object DiscardedValue extends PlainAttachment + /** Discarded pure expression observed at refchecks. */ + case object DiscardedExpr extends PlainAttachment } diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 714af26d4c70..f43311a37b60 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -88,6 +88,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.PermittedSubclassSymbols this.NamePos this.UnnamedArg + this.DiscardedValue + this.DiscardedExpr this.noPrint this.typeDebug // inaccessible: this.posAssigner diff --git a/test/async/jvm/toughtype.check b/test/async/jvm/toughtype.check index 1de9501259aa..8dcb3441e8d4 100644 --- a/test/async/jvm/toughtype.check +++ b/test/async/jvm/toughtype.check @@ -1,6 +1,3 @@ -toughtype.scala:175: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - identity[A] _ - ^ -toughtype.scala:175: warning: a pure expression does nothing in statement position +toughtype.scala:175: warning: discarded pure expression does nothing identity[A] _ ^ diff --git a/test/files/neg/discard-advice-a.check b/test/files/neg/discard-advice-a.check new file mode 100644 index 000000000000..acdcb1a30ca9 --- /dev/null +++ b/test/files/neg/discard-advice-a.check @@ -0,0 +1,12 @@ +discard-advice-a.scala:7: warning: unused value of type scala.concurrent.Future[Int] + Future(42) + ^ +discard-advice-a.scala:10: warning: unused value of type scala.concurrent.Future[Int] + Future(42) + ^ +discard-advice-a.scala:11: warning: unused value of type Boolean(true) + true + ^ +error: No warnings can be incurred under -Werror. +3 warnings +1 error diff --git a/test/files/neg/discard-advice-a.scala b/test/files/neg/discard-advice-a.scala new file mode 100644 index 000000000000..4e825ee92178 --- /dev/null +++ b/test/files/neg/discard-advice-a.scala @@ -0,0 +1,13 @@ +//> using options -Werror -Wnonunit-statement -Wvalue-discard + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/discard-advice-b.check b/test/files/neg/discard-advice-b.check new file mode 100644 index 000000000000..dc786b099b61 --- /dev/null +++ b/test/files/neg/discard-advice-b.check @@ -0,0 +1,9 @@ +discard-advice-b.scala:7: warning: discarded non-Unit value of type scala.concurrent.Future[Int] + Future(42) + ^ +discard-advice-b.scala:11: warning: discarded non-Unit value of type Boolean(true) + true + ^ +error: No warnings can be incurred under -Werror. +2 warnings +1 error diff --git a/test/files/neg/discard-advice-b.scala b/test/files/neg/discard-advice-b.scala new file mode 100644 index 000000000000..3ff081cff8eb --- /dev/null +++ b/test/files/neg/discard-advice-b.scala @@ -0,0 +1,13 @@ +//> using options -Werror -Wvalue-discard + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/discard-advice-c.check b/test/files/neg/discard-advice-c.check new file mode 100644 index 000000000000..f05cf5a48fb5 --- /dev/null +++ b/test/files/neg/discard-advice-c.check @@ -0,0 +1,6 @@ +discard-advice-c.scala:11: warning: discarded pure expression does nothing + true + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/discard-advice-c.scala b/test/files/neg/discard-advice-c.scala new file mode 100644 index 000000000000..c5784e09a9c0 --- /dev/null +++ b/test/files/neg/discard-advice-c.scala @@ -0,0 +1,13 @@ +//> using options -Werror + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/discard-advice-d.check b/test/files/neg/discard-advice-d.check new file mode 100644 index 000000000000..652de3b28504 --- /dev/null +++ b/test/files/neg/discard-advice-d.check @@ -0,0 +1,15 @@ +discard-advice-d.scala:7: warning: unused value of type scala.concurrent.Future[Int] +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other-pure-statement, site=C.f + Future(42) + ^ +discard-advice-d.scala:10: warning: unused value of type scala.concurrent.Future[Int] +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other-pure-statement, site=C.g + Future(42) + ^ +discard-advice-d.scala:11: warning: unused value of type Boolean(true) +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other-pure-statement, site=C.g + true + ^ +error: No warnings can be incurred under -Werror. +3 warnings +1 error diff --git a/test/files/neg/discard-advice-d.scala b/test/files/neg/discard-advice-d.scala new file mode 100644 index 000000000000..e685981bb6da --- /dev/null +++ b/test/files/neg/discard-advice-d.scala @@ -0,0 +1,13 @@ +//> using options -Wconf:any:warning-verbose -Werror -Wnonunit-statement -Wvalue-discard + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/nonunit-if.check b/test/files/neg/nonunit-if.check index 4d7726452c55..25039baffb26 100644 --- a/test/files/neg/nonunit-if.check +++ b/test/files/neg/nonunit-if.check @@ -1,9 +1,3 @@ -nonunit-if.scala:58: warning: discarded non-Unit value of type U - if (!isEmpty) f(a) // warn, check is on - ^ -nonunit-if.scala:62: warning: discarded non-Unit value of type Boolean - f(a) // warn, check is on - ^ nonunit-if.scala:13: warning: unused value of type scala.concurrent.Future[Int] improved // warn ^ @@ -53,5 +47,5 @@ nonunit-if.scala:146: warning: unused value of type String while (it.hasNext) it.next() // warn ^ error: No warnings can be incurred under -Werror. -18 warnings +16 warnings 1 error diff --git a/test/files/neg/t11379a.check b/test/files/neg/t11379a.check index a721a3dc57ff..e02fdb938bfd 100644 --- a/test/files/neg/t11379a.check +++ b/test/files/neg/t11379a.check @@ -3,23 +3,4 @@ t11379a.scala:17: error: type mismatch; required: Unit => Unit def test4: Either[Int, Unit] = Right(()).map(Right(())) ^ -t11379a.scala:9: warning: discarded non-Unit value of type scala.util.Right[Nothing,Unit] - def test1: Either[Int, Unit] = Right(Right(())) - ^ -t11379a.scala:10: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] - def test2: Either[Int, Unit] = Right(()).map(_ => unitRight[Int]) - ^ -t11379a.scala:11: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] - def test3: Either[Int, Unit] = Right(()).map { case _ => unitRight[Int] } - ^ -t11379a.scala:20: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] - def test5: Either[Int, Unit] = Right(()).map { case _ => unitRight } - ^ -t11379a.scala:21: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] - def test6: Either[Int, Unit] = Right(()).map { _ => unitRight } - ^ -t11379a.scala:22: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] - def test7: Either[Int, Unit] = Right(()).map(_ => unitRight) - ^ -6 warnings 1 error diff --git a/test/files/neg/t11379a2.check b/test/files/neg/t11379a2.check new file mode 100644 index 000000000000..06f7e46546c0 --- /dev/null +++ b/test/files/neg/t11379a2.check @@ -0,0 +1,21 @@ +t11379a2.scala:9: warning: discarded non-Unit value of type scala.util.Right[Nothing,Unit] + def test1: Either[Int, Unit] = Right(Right(())) + ^ +t11379a2.scala:10: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] + def test2: Either[Int, Unit] = Right(()).map(_ => unitRight[Int]) + ^ +t11379a2.scala:11: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] + def test3: Either[Int, Unit] = Right(()).map { case _ => unitRight[Int] } + ^ +t11379a2.scala:20: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] + def test5: Either[Int, Unit] = Right(()).map { case _ => unitRight } + ^ +t11379a2.scala:21: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] + def test6: Either[Int, Unit] = Right(()).map { _ => unitRight } + ^ +t11379a2.scala:22: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] + def test7: Either[Int, Unit] = Right(()).map(_ => unitRight) + ^ +error: No warnings can be incurred under -Werror. +6 warnings +1 error diff --git a/test/files/neg/t11379a2.scala b/test/files/neg/t11379a2.scala new file mode 100644 index 000000000000..7fe750ed3b77 --- /dev/null +++ b/test/files/neg/t11379a2.scala @@ -0,0 +1,23 @@ +// scalac: -Werror -Wvalue-discard +object UnitOfTrust { + import scala.util._ + + private def unitRight[A]: Either[A, Unit] = Right(()) + + // fails with: + // discarded non-Unit value + def test1: Either[Int, Unit] = Right(Right(())) + def test2: Either[Int, Unit] = Right(()).map(_ => unitRight[Int]) + def test3: Either[Int, Unit] = Right(()).map { case _ => unitRight[Int] } + + // fails with: + // error: type mismatch; + // found : scala.util.Right[Nothing,Unit] + // required: Unit => Unit + //def test4: Either[Int, Unit] = Right(()).map(Right(())) + + // was: compiles just fine + def test5: Either[Int, Unit] = Right(()).map { case _ => unitRight } + def test6: Either[Int, Unit] = Right(()).map { _ => unitRight } + def test7: Either[Int, Unit] = Right(()).map(_ => unitRight) +} diff --git a/test/files/neg/t12495.check b/test/files/neg/t12495.check index 52c058692538..bf735c969070 100644 --- a/test/files/neg/t12495.check +++ b/test/files/neg/t12495.check @@ -1,12 +1,12 @@ -t12495.scala:4: warning: discarded non-Unit value of type (Int, Int) - def g = f(42, 27) - ^ t12495.scala:4: warning: adapted the argument list to expected Unit type: arguments will be discarded signature: Function1.apply(v1: T1): R given arguments: 42, 27 after adaptation: Function1((42, 27): Unit) def g = f(42, 27) ^ +t12495.scala:4: warning: discarded non-Unit value of type (Int, Int) + def g = f(42, 27) + ^ error: No warnings can be incurred under -Werror. 2 warnings 1 error diff --git a/test/files/neg/t9847.check b/test/files/neg/t9847.check index d6d18fed0a4d..d10c0e852288 100644 --- a/test/files/neg/t9847.check +++ b/test/files/neg/t9847.check @@ -1,6 +1,12 @@ t9847.scala:6: warning: discarded non-Unit value of type Int(42) def f(): Unit = 42 ^ +t9847.scala:9: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 + ^ +t9847.scala:13: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 + ^ t9847.scala:14: warning: discarded non-Unit value of type Int(1) + 1 ^ @@ -10,21 +16,6 @@ t9847.scala:18: warning: discarded non-Unit value of type Int t9847.scala:21: warning: discarded non-Unit value of type Int def j(): Unit = x + 1 ^ -t9847.scala:6: warning: a pure expression does nothing in statement position - def f(): Unit = 42 - ^ -t9847.scala:9: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 1 - ^ -t9847.scala:13: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 1 - ^ -t9847.scala:14: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - + 1 - ^ -t9847.scala:14: warning: a pure expression does nothing in statement position - + 1 - ^ t9847.scala:23: warning: a pure expression does nothing in statement position class C { 42 } ^ @@ -35,5 +26,5 @@ t9847.scala:24: warning: a pure expression does nothing in statement position; m class D { 42 ; 17 } ^ error: No warnings can be incurred under -Werror. -12 warnings +9 warnings 1 error diff --git a/test/files/run/contrib674.check b/test/files/run/contrib674.check index 7fcac8e06d44..491bb717fbb0 100644 --- a/test/files/run/contrib674.check +++ b/test/files/run/contrib674.check @@ -1,6 +1,3 @@ -contrib674.scala:15: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - 1 - ^ -contrib674.scala:15: warning: a pure expression does nothing in statement position +contrib674.scala:15: warning: discarded pure expression does nothing 1 ^ diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check index 7e38494250da..5f5316e74382 100644 --- a/test/files/run/names-defaults.check +++ b/test/files/run/names-defaults.check @@ -22,10 +22,7 @@ names-defaults.scala:280: warning: local val v in method foo is never used names-defaults.scala:280: warning: local val u in method foo is never used class A2489x2 { def foo(): Unit = { val v = 10; def bar(a: Int = 1, b: Int = 2) = a; bar(); val u = 0 } } ^ -names-defaults.scala:269: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - spawn(b = { val ttt = 1; ttt }, a = 0) - ^ -names-defaults.scala:269: warning: a pure expression does nothing in statement position +names-defaults.scala:269: warning: discarded pure expression does nothing spawn(b = { val ttt = 1; ttt }, a = 0) ^ 1: @ diff --git a/test/files/run/patmatnew.check b/test/files/run/patmatnew.check index ff9eb4579d7e..cc42f919a9f1 100644 --- a/test/files/run/patmatnew.check +++ b/test/files/run/patmatnew.check @@ -4,16 +4,10 @@ patmatnew.scala:673: warning: This catches all Throwables. If this is really int patmatnew.scala:354: warning: a pure expression does nothing in statement position case 1 => "OK" ^ -patmatnew.scala:355: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected +patmatnew.scala:355: warning: discarded pure expression does nothing case 2 => assert(false); "KO" ^ -patmatnew.scala:355: warning: a pure expression does nothing in statement position - case 2 => assert(false); "KO" - ^ -patmatnew.scala:356: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - case 3 => assert(false); "KO" - ^ -patmatnew.scala:356: warning: a pure expression does nothing in statement position +patmatnew.scala:356: warning: discarded pure expression does nothing case 3 => assert(false); "KO" ^ patmatnew.scala:178: warning: match may not be exhaustive. diff --git a/test/files/run/repl-paste-error.check b/test/files/run/repl-paste-error.check index 5842b7bdc2cf..265b69e83d5d 100644 --- a/test/files/run/repl-paste-error.check +++ b/test/files/run/repl-paste-error.check @@ -15,11 +15,7 @@ END 42 ^ -:3: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - - 42 - ^ -:3: warning: a pure expression does nothing in statement position +:3: warning: discarded pure expression does nothing def f(): Unit scala> :quit diff --git a/test/files/run/t3488.check b/test/files/run/t3488.check deleted file mode 100644 index 7799c78d9769..000000000000 --- a/test/files/run/t3488.check +++ /dev/null @@ -1,14 +0,0 @@ -t3488.scala:4: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - println(foo { val List(_*)=List(0); 1 } ()) - ^ -t3488.scala:4: warning: a pure expression does nothing in statement position - println(foo { val List(_*)=List(0); 1 } ()) - ^ -t3488.scala:5: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - println(foo { val List(_*)=List(0); 1 } (1)) - ^ -t3488.scala:5: warning: a pure expression does nothing in statement position - println(foo { val List(_*)=List(0); 1 } (1)) - ^ -0 -1 diff --git a/test/files/run/t3488.scala b/test/files/run/t3488.scala index a8cfa9b808d8..92295ca5a1db 100644 --- a/test/files/run/t3488.scala +++ b/test/files/run/t3488.scala @@ -1,6 +1,8 @@ +//> using options -Wconf:cat=other-pure-statement:silent + object Test extends App { - def foo(p: => Unit)(x:Int = 0) = x + def foo(p: => Unit)(x: Int = 0) = x - println(foo { val List(_*)=List(0); 1 } ()) - println(foo { val List(_*)=List(0); 1 } (1)) + assert(foo { val List(_*)=List(0); 42 } () == 0) + assert(foo { val List(_*)=List(0); 42 } (1) == 1) }