diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 6e5fe00345f4..77298783fae3 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.attachments.containsElement(DiscardedValue) && { + t.setAttachments(t.attachments.removeElement(DiscardedValue)) + 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 { @@ -1919,10 +1926,10 @@ abstract class RefChecks extends Transform { } case _ => t } - def msg = s"unused value of type ${where.tpe} (add `: Unit` to discard silently)" + 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 = { @@ -1967,7 +1974,7 @@ abstract class RefChecks extends Transform { for (stat <- body) if (!checkInterestingResultInStatement(stat) && treeInfo.isPureExprForWarningPurposes(stat)) { val msg = "a pure expression does nothing in statement position" - val clause = if (body.lengthCompare(1) > 0) "; multiline expressions may require enclosing parentheses" else "" + val clause = if (body.lengthCompare(2) > 0) "; multiline expressions may require enclosing parentheses" else "" refchecksWarning(stat.pos, s"$msg$clause", WarningCategory.OtherPureStatement) } validateBaseTypes(currentOwner) @@ -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.attachments.containsElement(DiscardedExpr)) { + t.setAttachments(t.attachments.removeElement(DiscardedExpr)) + "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 = { def loop(t: Tree): Unit = diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 3489802b9cad..c75facd590f4 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/jvm/innerClassAttribute.check b/test/files/jvm/innerClassAttribute.check index bb293a93ada1..d43971dce825 100644 --- a/test/files/jvm/innerClassAttribute.check +++ b/test/files/jvm/innerClassAttribute.check @@ -4,7 +4,7 @@ Classes_1.scala:117: warning: a pure expression does nothing in statement positi Classes_1.scala:124: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses ((x: String) => x + "2") ^ -Classes_1.scala:129: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +Classes_1.scala:129: warning: a pure expression does nothing in statement position (s: String) => { ^ Classes_1.scala:130: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses 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 d1ffb1337ef3..25039baffb26 100644 --- a/test/files/neg/nonunit-if.check +++ b/test/files/neg/nonunit-if.check @@ -1,57 +1,51 @@ -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] (add `: Unit` to discard silently) +nonunit-if.scala:13: warning: unused value of type scala.concurrent.Future[Int] improved // warn ^ -nonunit-if.scala:20: warning: unused value of type String (add `: Unit` to discard silently) +nonunit-if.scala:20: warning: unused value of type String new E().toString // warn ^ -nonunit-if.scala:26: warning: unused value of type scala.concurrent.Future[Int] (add `: Unit` to discard silently) +nonunit-if.scala:26: warning: unused value of type scala.concurrent.Future[Int] Future(42) // warn ^ -nonunit-if.scala:30: warning: unused value of type K (add `: Unit` to discard silently) +nonunit-if.scala:30: warning: unused value of type K copy() // warn ^ -nonunit-if.scala:37: warning: unused value of type List[Int] (add `: Unit` to discard silently) +nonunit-if.scala:37: warning: unused value of type List[Int] 27 +: xs // warn ^ nonunit-if.scala:44: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses null // warn for purity ^ -nonunit-if.scala:58: warning: unused value of type U (add `: Unit` to discard silently) +nonunit-if.scala:58: warning: unused value of type U if (!isEmpty) f(a) // warn, check is on ^ -nonunit-if.scala:62: warning: unused value of type Boolean (add `: Unit` to discard silently) +nonunit-if.scala:62: warning: unused value of type Boolean f(a) // warn, check is on ^ -nonunit-if.scala:73: warning: unused value of type U (add `: Unit` to discard silently) +nonunit-if.scala:73: warning: unused value of type U if (!fellback) action(z) // warn, check is on ^ -nonunit-if.scala:81: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:81: warning: unused value of type Int g // warn, check is on ^ -nonunit-if.scala:79: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:79: warning: unused value of type Int g // warn block statement ^ -nonunit-if.scala:86: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:86: warning: unused value of type Int g // warn ^ -nonunit-if.scala:84: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:84: warning: unused value of type Int g // warn ^ -nonunit-if.scala:96: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:96: warning: unused value of type Int if (b) { // warn, at least one branch looks interesting ^ -nonunit-if.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] (add `: Unit` to discard silently) +nonunit-if.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] set += a // warn because cannot know whether the `set` was supposed to be consumed or assigned ^ -nonunit-if.scala:146: warning: unused value of type String (add `: Unit` to discard silently) +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/nonunit-statement.check b/test/files/neg/nonunit-statement.check index b15ae34fb7fd..2a5f1ae9c21d 100644 --- a/test/files/neg/nonunit-statement.check +++ b/test/files/neg/nonunit-statement.check @@ -1,39 +1,42 @@ -nonunit-statement.scala:13: warning: unused value of type scala.concurrent.Future[Int] (add `: Unit` to discard silently) +nonunit-statement.scala:13: warning: unused value of type scala.concurrent.Future[Int] improved // warn ^ -nonunit-statement.scala:20: warning: unused value of type String (add `: Unit` to discard silently) +nonunit-statement.scala:20: warning: unused value of type String new E().toString // warn ^ -nonunit-statement.scala:26: warning: unused value of type scala.concurrent.Future[Int] (add `: Unit` to discard silently) +nonunit-statement.scala:26: warning: unused value of type scala.concurrent.Future[Int] Future(42) // warn ^ -nonunit-statement.scala:30: warning: unused value of type K (add `: Unit` to discard silently) +nonunit-statement.scala:30: warning: unused value of type K copy() // warn ^ -nonunit-statement.scala:37: warning: unused value of type List[Int] (add `: Unit` to discard silently) +nonunit-statement.scala:37: warning: unused value of type List[Int] 27 +: xs // warn ^ nonunit-statement.scala:44: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses null // warn for purity ^ -nonunit-statement.scala:79: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:79: warning: unused value of type Int g // warn block statement ^ -nonunit-statement.scala:86: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:86: warning: unused value of type Int g // warn ^ -nonunit-statement.scala:84: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:84: warning: unused value of type Int g // warn ^ -nonunit-statement.scala:96: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:96: warning: unused value of type Int if (b) { // warn, at least one branch looks interesting ^ -nonunit-statement.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] (add `: Unit` to discard silently) +nonunit-statement.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] set += a // warn because cannot know whether the `set` was supposed to be consumed or assigned ^ -nonunit-statement.scala:146: warning: unused value of type String (add `: Unit` to discard silently) +nonunit-statement.scala:146: warning: unused value of type String while (it.hasNext) it.next() // warn ^ +nonunit-statement.scala:202: warning: a pure expression does nothing in statement position + null // warn for purity, but does not cause multiline clause + ^ error: No warnings can be incurred under -Werror. -12 warnings +13 warnings 1 error diff --git a/test/files/neg/nonunit-statement.scala b/test/files/neg/nonunit-statement.scala index 192091dbd034..b411249e5084 100644 --- a/test/files/neg/nonunit-statement.scala +++ b/test/files/neg/nonunit-statement.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wnonunit-statement -Wnonunit-if:false -Wvalue-discard +//> using options -Werror -Wnonunit-statement -Wnonunit-if:false -Wvalue-discard // debug: -Vprint:refchecks -Yprint-trees:format import collection.ArrayOps import collection.mutable.{ArrayBuilder, LinkedHashSet, ListBuffer} @@ -197,3 +197,7 @@ class Depends { () } } +// some uninteresting expressions may warn for other reasons +class NotMultiline { + null // warn for purity, but does not cause multiline clause +} 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 66898657f212..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,22 +16,7 @@ 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; multiline expressions may require enclosing parentheses +t9847.scala:23: warning: a pure expression does nothing in statement position class C { 42 } ^ t9847.scala:24: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses @@ -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/macro-duplicate.check b/test/files/run/macro-duplicate.check index 7006b1661162..136e30c8a8d3 100644 --- a/test/files/run/macro-duplicate.check +++ b/test/files/run/macro-duplicate.check @@ -1,3 +1,3 @@ -Test_2.scala:5: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +Test_2.scala:5: warning: a pure expression does nothing in statement position Macros.foo ^ 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) } diff --git a/test/files/run/t4680.check b/test/files/run/t4680.check index f0ac8f491fb3..aaa0259a78d6 100644 --- a/test/files/run/t4680.check +++ b/test/files/run/t4680.check @@ -1,12 +1,9 @@ -t4680.scala:51: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +t4680.scala:53: warning: a pure expression does nothing in statement position new C { 5 } ^ -t4680.scala:69: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +t4680.scala:71: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses new { val x = 5 } with E() { 5 } ^ -warning: 1 deprecation (since 2.11.0) -warning: 4 deprecations (since 2.13.0) -warning: 5 deprecations in total; re-run with -deprecation for details // new C { } diff --git a/test/files/run/t4680.scala b/test/files/run/t4680.scala index aa1a42c52351..294cc6d40fb4 100644 --- a/test/files/run/t4680.scala +++ b/test/files/run/t4680.scala @@ -1,3 +1,5 @@ +//> using options -Wconf:cat=deprecation:s + trait A extends DelayedInit { print("-A ") diff --git a/test/files/run/t7047.check b/test/files/run/t7047.check index 129ce3eeca22..da44c8ad4871 100644 --- a/test/files/run/t7047.check +++ b/test/files/run/t7047.check @@ -1,3 +1,3 @@ -Test_2.scala:2: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +Test_2.scala:2: warning: a pure expression does nothing in statement position Macros.foo ^