Skip to content

Commit d5d5701

Browse files
authored
Merge pull request #134 from scala/backport-lts-3.3-21927
Backport "Allow discarding "Discarded non-Unit" warnings with `: Unit`" to 3.3 LTS
2 parents 161aef9 + 7f6d6b6 commit d5d5701

15 files changed

+86
-37
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -2429,7 +2429,7 @@ class PureExpressionInStatementPosition(stat: untpd.Tree, val exprOwner: Symbol)
24292429
class PureUnitExpression(stat: untpd.Tree, tpe: Type)(using Context)
24302430
extends Message(PureUnitExpressionID) {
24312431
def kind = MessageKind.PotentialIssue
2432-
def msg(using Context) = i"Discarded non-Unit value of type ${tpe.widen}. You may want to use `()`."
2432+
def msg(using Context) = i"Discarded non-Unit value of type ${tpe.widen}. Add `: Unit` to discard silently."
24332433
def explain(using Context) =
24342434
i"""As this expression is not of type Unit, it is desugared into `{ $stat; () }`.
24352435
|Here the `$stat` expression is a pure statement that can be discarded.
@@ -3133,7 +3133,7 @@ class InlinedAnonClassWarning()(using Context)
31333133
class ValueDiscarding(tp: Type)(using Context)
31343134
extends Message(ValueDiscardingID):
31353135
def kind = MessageKind.PotentialIssue
3136-
def msg(using Context) = i"discarded non-Unit value of type $tp"
3136+
def msg(using Context) = i"discarded non-Unit value of type ${tp.widen}. Add `: Unit` to discard silently."
31373137
def explain(using Context) = ""
31383138

31393139
class UnusedNonUnitValue(tp: Type)(using Context)

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

+18-4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ object Typer {
7474
/** An attachment for GADT constraints that were inferred for a pattern. */
7575
val InferredGadtConstraints = new Property.StickyKey[core.GadtConstraint]
7676

77+
/** Indicates that an expression is explicitly ascribed to [[Unit]] type. */
78+
val AscribedToUnit = new Property.StickyKey[Unit]
79+
7780
/** An attachment on a Select node with an `apply` field indicating that the `apply`
7881
* was inserted by the Typer.
7982
*/
@@ -992,7 +995,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
992995
else tpt
993996
val expr1 =
994997
if isWildcard then tree.expr.withType(underlyingTreeTpe.tpe)
995-
else typed(tree.expr, underlyingTreeTpe.tpe.widenSkolem)
998+
else
999+
if underlyingTreeTpe.tpe.isRef(defn.UnitClass) then
1000+
untpd.unsplice(tree.expr).putAttachment(AscribedToUnit, ())
1001+
typed(tree.expr, underlyingTreeTpe.tpe.widenSkolem)
9961002
assignType(cpy.Typed(tree)(expr1, tpt), underlyingTreeTpe)
9971003
.withNotNullInfo(expr1.notNullInfo)
9981004
}
@@ -3009,7 +3015,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
30093015
else if (ctx.mode.is(Mode.Pattern))
30103016
typedUnApply(cpy.Apply(tree)(op, l :: r :: Nil), pt)
30113017
else {
3012-
val app = typedApply(desugar.binop(l, op, r), pt)
3018+
val app = typedApply(desugar.binop(l, op, r).withAttachmentsFrom(tree), pt)
30133019
if op.name.isRightAssocOperatorName && !ctx.mode.is(Mode.QuotedPattern) then
30143020
val defs = new mutable.ListBuffer[Tree]
30153021
def lift(app: Tree): Tree = (app: @unchecked) match
@@ -4221,9 +4227,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
42214227
// so will take the code path that decides on inlining
42224228
val tree1 = adapt(tree, WildcardType, locked)
42234229
checkStatementPurity(tree1)(tree, ctx.owner, isUnitExpr = true)
4224-
if (!ctx.isAfterTyper && !tree.isInstanceOf[Inlined] && ctx.settings.Whas.valueDiscard && !isThisTypeResult(tree)) {
4230+
4231+
if ctx.settings.Whas.valueDiscard
4232+
&& !ctx.isAfterTyper
4233+
&& !tree.isInstanceOf[Inlined]
4234+
&& !isThisTypeResult(tree)
4235+
&& !tree.hasAttachment(AscribedToUnit) then
42254236
report.warning(ValueDiscarding(tree.tpe), tree.srcPos)
4226-
}
4237+
42274238
return tpd.Block(tree1 :: Nil, unitLiteral)
42284239
}
42294240

@@ -4578,6 +4589,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
45784589
// sometimes we do not have the original anymore and use the transformed tree instead.
45794590
// But taken together, the two criteria are quite accurate.
45804591
missingArgs(tree, tree.tpe.widen)
4592+
case _ if tree.hasAttachment(AscribedToUnit) =>
4593+
// The tree was ascribed to `Unit` explicitly to silence the warning.
4594+
()
45814595
case _ if isUnitExpr =>
45824596
report.warning(PureUnitExpression(original, tree.tpe), original.srcPos)
45834597
case _ =>

tests/neg-custom-args/captures/real-try.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- [E190] Potential Issue Warning: tests/neg-custom-args/captures/real-try.scala:30:4 ----------------------------------
22
30 | b.x
33
| ^^^
4-
| Discarded non-Unit value of type () -> Unit. You may want to use `()`.
4+
| Discarded non-Unit value of type () -> Unit. Add `: Unit` to discard silently.
55
|
66
| longer explanation available when compiling with `-explain`
77
-- Error: tests/neg-custom-args/captures/real-try.scala:12:2 -----------------------------------------------------------

tests/neg/i13091.check

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Error: tests/neg/i13091.scala:7:16 ----------------------------------------------------------------------------------
2+
7 |def test = (new Foo): Unit // error: class Foo is marked @experimental ...
3+
| ^^^
4+
| class Foo is marked @experimental and therefore may only be used in an experimental scope.

tests/neg/i13091.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ import annotation.experimental
44

55
@experimental class Foo
66

7-
def test: Unit = new Foo // error: class Foo is marked @experimental ...
7+
def test = (new Foo): Unit // error: class Foo is marked @experimental ...

tests/neg/i18408a.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
-- [E190] Potential Issue Warning: tests/neg/i18408a.scala:3:15 --------------------------------------------------------
88
3 |def test1 = fa(42)
99
| ^^
10-
| Discarded non-Unit value of type Int. You may want to use `()`.
10+
| Discarded non-Unit value of type Int. Add `: Unit` to discard silently.
1111
|
1212
| longer explanation available when compiling with `-explain`
1313
-- [E129] Potential Issue Warning: tests/neg/i18408a.scala:4:16 --------------------------------------------------------

tests/neg/i18408b.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
-- [E190] Potential Issue Warning: tests/neg/i18408b.scala:3:15 --------------------------------------------------------
88
3 |def test1 = fa(42)
99
| ^^
10-
| Discarded non-Unit value of type Int. You may want to use `()`.
10+
| Discarded non-Unit value of type Int. Add `: Unit` to discard silently.
1111
|
1212
| longer explanation available when compiling with `-explain`
1313
-- [E129] Potential Issue Warning: tests/neg/i18408b.scala:4:16 --------------------------------------------------------

tests/neg/i18408c.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
-- [E190] Potential Issue Warning: tests/neg/i18408c.scala:3:15 --------------------------------------------------------
88
3 |def test1 = fa(42)
99
| ^^
10-
| Discarded non-Unit value of type Int. You may want to use `()`.
10+
| Discarded non-Unit value of type Int. Add `: Unit` to discard silently.
1111
|
1212
| longer explanation available when compiling with `-explain`
1313
-- [E129] Potential Issue Warning: tests/neg/i18408c.scala:4:16 --------------------------------------------------------

tests/neg/spaces-vs-tabs.check

-6
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,3 @@
2828
| The start of this line does not match any of the previous indentation widths.
2929
| Indentation width of current line : 1 tab, 2 spaces
3030
| This falls between previous widths: 1 tab and 1 tab, 4 spaces
31-
-- [E190] Potential Issue Warning: tests/neg/spaces-vs-tabs.scala:13:7 -------------------------------------------------
32-
13 | 1
33-
| ^
34-
| Discarded non-Unit value of type Int. You may want to use `()`.
35-
|
36-
| longer explanation available when compiling with `-explain`

tests/neg/spaces-vs-tabs.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ object Test:
1010
object Test2:
1111

1212
if true then
13-
1
13+
()
1414
else 2 // error
1515

tests/warn/21557.check

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- [E190] Potential Issue Warning: tests/warn/21557.scala:9:16 ---------------------------------------------------------
2+
9 | val x: Unit = 1 + 1 // warn
3+
| ^^^^^
4+
| Discarded non-Unit value of type Int. Add `: Unit` to discard silently.
5+
|
6+
| longer explanation available when compiling with `-explain`
7+
-- [E176] Potential Issue Warning: tests/warn/21557.scala:10:2 ---------------------------------------------------------
8+
10 | 1 + 1 // warn
9+
| ^^^^^
10+
| unused value of type (2 : Int)
11+
-- [E175] Potential Issue Warning: tests/warn/21557.scala:15:52 --------------------------------------------------------
12+
15 | val x1: Unit = new Assertion("another").shouldPass() // warn (enabled by -Wvalue-discard)
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
| discarded non-Unit value of type Assertion. Add `: Unit` to discard silently.
15+
-- [E176] Potential Issue Warning: tests/warn/21557.scala:16:41 --------------------------------------------------------
16+
16 | new Assertion("yet another").shouldPass() // warn (enabled by -Wnonunit-statement)
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
| unused value of type Assertion

tests/warn/21557.scala

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//> using options -Wvalue-discard -Wnonunit-statement
2+
3+
class Assertion(assert: => Any):
4+
def shouldPass(): Assertion = ???
5+
6+
def test: Unit =
7+
1 + 1: Unit
8+
(1 + 1): Unit
9+
val x: Unit = 1 + 1 // warn
10+
1 + 1 // warn
11+
val y: Int = 1 + 1
12+
13+
new Assertion("").shouldPass(): Unit
14+
(new Assertion("").shouldPass()): Unit
15+
val x1: Unit = new Assertion("another").shouldPass() // warn (enabled by -Wvalue-discard)
16+
new Assertion("yet another").shouldPass() // warn (enabled by -Wnonunit-statement)
17+
val y1: Assertion = new Assertion("another other").shouldPass()
18+
19+
()

tests/warn/i18722.check

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- [E190] Potential Issue Warning: tests/warn/i18722.scala:3:15 --------------------------------------------------------
22
3 |def f1: Unit = null // warn
33
| ^^^^
4-
| Discarded non-Unit value of type Null. You may want to use `()`.
4+
| Discarded non-Unit value of type Null. Add `: Unit` to discard silently.
55
|---------------------------------------------------------------------------------------------------------------------
66
| Explanation (enabled by `-explain`)
77
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -12,7 +12,7 @@
1212
-- [E190] Potential Issue Warning: tests/warn/i18722.scala:4:15 --------------------------------------------------------
1313
4 |def f2: Unit = 1 // warn
1414
| ^
15-
| Discarded non-Unit value of type Int. You may want to use `()`.
15+
| Discarded non-Unit value of type Int. Add `: Unit` to discard silently.
1616
|---------------------------------------------------------------------------------------------------------------------
1717
| Explanation (enabled by `-explain`)
1818
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -23,7 +23,7 @@
2323
-- [E190] Potential Issue Warning: tests/warn/i18722.scala:5:15 --------------------------------------------------------
2424
5 |def f3: Unit = "a" // warn
2525
| ^^^
26-
| Discarded non-Unit value of type String. You may want to use `()`.
26+
| Discarded non-Unit value of type String. Add `: Unit` to discard silently.
2727
|---------------------------------------------------------------------------------------------------------------------
2828
| Explanation (enabled by `-explain`)
2929
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -34,7 +34,7 @@
3434
-- [E190] Potential Issue Warning: tests/warn/i18722.scala:7:15 --------------------------------------------------------
3535
7 |def f4: Unit = i // warn
3636
| ^
37-
| Discarded non-Unit value of type Int. You may want to use `()`.
37+
| Discarded non-Unit value of type Int. Add `: Unit` to discard silently.
3838
|---------------------------------------------------------------------------------------------------------------------
3939
| Explanation (enabled by `-explain`)
4040
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

tests/warn/nonunit-statement.check

+10-10
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,31 @@
2727
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:58:19 --------------------------------------------
2828
58 | if (!isEmpty) f(a) // warn (if)
2929
| ^^^^
30-
| discarded non-Unit value of type U
30+
| discarded non-Unit value of type U. Add `: Unit` to discard silently.
3131
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:62:7 ---------------------------------------------
3232
62 | f(a) // warn (if)
3333
| ^^^^
34-
| discarded non-Unit value of type Boolean
34+
| discarded non-Unit value of type Boolean. Add `: Unit` to discard silently.
3535
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:73:25 --------------------------------------------
3636
73 | if (!fellback) action(z) // warn (if)
3737
| ^^^^^^^^^
38-
| discarded non-Unit value of type U
38+
| discarded non-Unit value of type U. Add `: Unit` to discard silently.
3939
-- [E176] Potential Issue Warning: tests/warn/nonunit-statement.scala:79:6 ---------------------------------------------
4040
79 | g // warn block statement
4141
| ^
4242
| unused value of type (g : => Int)
4343
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:81:6 ---------------------------------------------
4444
81 | g // warn (if)
4545
| ^
46-
| discarded non-Unit value of type (g : => Int)
46+
| discarded non-Unit value of type Int. Add `: Unit` to discard silently.
4747
-- [E176] Potential Issue Warning: tests/warn/nonunit-statement.scala:84:6 ---------------------------------------------
4848
84 | g // warn
4949
| ^
5050
| unused value of type (g : => Int)
5151
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:86:6 ---------------------------------------------
5252
86 | g // warn
5353
| ^
54-
| discarded non-Unit value of type (g : => Int)
54+
| discarded non-Unit value of type Int. Add `: Unit` to discard silently.
5555
-- [E176] Potential Issue Warning: tests/warn/nonunit-statement.scala:96:4 ---------------------------------------------
5656
96 | if (b) { // warn, at least one branch looks interesting
5757
| ^
@@ -70,20 +70,20 @@
7070
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:126:37 -------------------------------------------
7171
126 | if (start.length != 0) jsb.append(start) // warn (value-discard)
7272
| ^^^^^^^^^^^^^^^^^
73-
| discarded non-Unit value of type StringBuilder
73+
| discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently.
7474
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:132:18 -------------------------------------------
7575
132 | jsb.append(it.next()) // warn (value-discard)
7676
| ^^^^^^^^^^^^^^^^^^^^^
77-
| discarded non-Unit value of type StringBuilder
77+
| discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently.
7878
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:135:35 -------------------------------------------
7979
135 | if (end.length != 0) jsb.append(end) // warn (value-discard)
8080
| ^^^^^^^^^^^^^^^
81-
| discarded non-Unit value of type StringBuilder
81+
| discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently.
8282
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:141:14 -------------------------------------------
8383
141 | b.append(it.next()) // warn (value-discard)
8484
| ^^^^^^^^^^^^^^^^^^^
85-
| discarded non-Unit value of type StringBuilder
85+
| discarded non-Unit value of type StringBuilder. Add `: Unit` to discard silently.
8686
-- [E175] Potential Issue Warning: tests/warn/nonunit-statement.scala:146:30 -------------------------------------------
8787
146 | while (it.hasNext) it.next() // warn
8888
| ^^^^^^^^^
89-
| discarded non-Unit value of type String
89+
| discarded non-Unit value of type String. Add `: Unit` to discard silently.

tests/warn/warn-value-discard.check

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:27:36 -------------------------------------------
22
27 | mutable.Set.empty[String].remove("") // warn
33
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4-
| discarded non-Unit value of type Boolean
4+
| discarded non-Unit value of type Boolean. Add `: Unit` to discard silently.
55
-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:39:41 -------------------------------------------
66
39 | mutable.Set.empty[String].subtractOne("") // warn
77
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8-
| discarded non-Unit value of type scala.collection.mutable.Set[String]
8+
| discarded non-Unit value of type scala.collection.mutable.Set[String]. Add `: Unit` to discard silently.
99
-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:59:4 --------------------------------------------
1010
59 | mutable.Set.empty[String] += "" // warn
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
| discarded non-Unit value of type scala.collection.mutable.Set[String]
12+
| discarded non-Unit value of type scala.collection.mutable.Set[String]. Add `: Unit` to discard silently.
1313
-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:15:35 -------------------------------------------
1414
15 | firstThing().map(_ => secondThing()) // warn
1515
| ^^^^^^^^^^^^^
16-
| discarded non-Unit value of type Either[Failed, Unit]
16+
| discarded non-Unit value of type Either[Failed, Unit]. Add `: Unit` to discard silently.
1717
-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:18:35 -------------------------------------------
1818
18 | firstThing().map(_ => secondThing()) // warn
1919
| ^^^^^^^^^^^^^
20-
| discarded non-Unit value of type Either[Failed, Unit]
20+
| discarded non-Unit value of type Either[Failed, Unit]. Add `: Unit` to discard silently.

0 commit comments

Comments
 (0)