Skip to content

Commit 46cd256

Browse files
mbovelnmcbrochala
committed
Allow discarding "Discarded non-Unit" warnings with : Unit
Co-Authored-By: nmc.borst <1698211+nmcb@users.noreply.github.com> Co-Authored-By: Jędrzej Rochala <48657087+rochala@users.noreply.github.com>
1 parent 1947828 commit 46cd256

15 files changed

+90
-51
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -2469,7 +2469,7 @@ class PureExpressionInStatementPosition(stat: untpd.Tree, val exprOwner: Symbol)
24692469
class PureUnitExpression(stat: untpd.Tree, tpe: Type)(using Context)
24702470
extends Message(PureUnitExpressionID) {
24712471
def kind = MessageKind.PotentialIssue
2472-
def msg(using Context) = i"Discarded non-Unit value of type ${tpe.widen}. You may want to use `()`."
2472+
def msg(using Context) = i"Discarded non-Unit value of type ${tpe.widen}. Add `: Unit` to discard silently."
24732473
def explain(using Context) =
24742474
i"""As this expression is not of type Unit, it is desugared into `{ $stat; () }`.
24752475
|Here the `$stat` expression is a pure statement that can be discarded.
@@ -3173,7 +3173,7 @@ class InlinedAnonClassWarning()(using Context)
31733173
class ValueDiscarding(tp: Type)(using Context)
31743174
extends Message(ValueDiscardingID):
31753175
def kind = MessageKind.PotentialIssue
3176-
def msg(using Context) = i"discarded non-Unit value of type $tp"
3176+
def msg(using Context) = i"discarded non-Unit value of type ${tp.widen}. Add `: Unit` to discard silently."
31773177
def explain(using Context) = ""
31783178

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

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

+18-4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ object Typer {
8181
/** Indicates that a definition was copied over from the parent refinements */
8282
val RefinementFromParent = new Property.StickyKey[Unit]
8383

84+
/** Indicates that an expression is explicitly ascribed to [[Unit]] type. */
85+
val AscribedToUnit = new Property.StickyKey[Unit]
86+
8487
/** An attachment on a Select node with an `apply` field indicating that the `apply`
8588
* was inserted by the Typer.
8689
*/
@@ -1193,7 +1196,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
11931196
else tpt
11941197
val expr1 =
11951198
if isWildcard then tree.expr.withType(underlyingTreeTpe.tpe)
1196-
else typed(tree.expr, underlyingTreeTpe.tpe.widenSkolem)
1199+
else
1200+
if underlyingTreeTpe.tpe.isRef(defn.UnitClass) then
1201+
untpd.unsplice(tree.expr).putAttachment(AscribedToUnit, ())
1202+
typed(tree.expr, underlyingTreeTpe.tpe.widenSkolem)
11971203
assignType(cpy.Typed(tree)(expr1, tpt), underlyingTreeTpe)
11981204
.withNotNullInfo(expr1.notNullInfo)
11991205
}
@@ -3377,7 +3383,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
33773383
else if (ctx.mode.is(Mode.Pattern))
33783384
typedUnApply(cpy.Apply(tree)(op, l :: r :: Nil), pt)
33793385
else {
3380-
val app = typedApply(desugar.binop(l, op, r), pt)
3386+
val app = typedApply(desugar.binop(l, op, r).withAttachmentsFrom(tree), pt)
33813387
if op.name.isRightAssocOperatorName && !ctx.mode.is(Mode.QuotedExprPattern) then
33823388
val defs = new mutable.ListBuffer[Tree]
33833389
def lift(app: Tree): Tree = (app: @unchecked) match
@@ -4581,9 +4587,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
45814587
// so will take the code path that decides on inlining
45824588
val tree1 = adapt(tree, WildcardType, locked)
45834589
checkStatementPurity(tree1)(tree, ctx.owner, isUnitExpr = true)
4584-
if (!ctx.isAfterTyper && !tree.isInstanceOf[Inlined] && ctx.settings.Whas.valueDiscard && !isThisTypeResult(tree)) {
4590+
4591+
if ctx.settings.Whas.valueDiscard
4592+
&& !ctx.isAfterTyper
4593+
&& !tree.isInstanceOf[Inlined]
4594+
&& !isThisTypeResult(tree)
4595+
&& !tree.hasAttachment(AscribedToUnit) then
45854596
report.warning(ValueDiscarding(tree.tpe), tree.srcPos)
4586-
}
4597+
45874598
return tpd.Block(tree1 :: Nil, unitLiteral)
45884599
}
45894600

@@ -4839,6 +4850,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
48394850
// sometimes we do not have the original anymore and use the transformed tree instead.
48404851
// But taken together, the two criteria are quite accurate.
48414852
missingArgs(tree, tree.tpe.widen)
4853+
case _ if tree.hasAttachment(AscribedToUnit) =>
4854+
// The tree was ascribed to `Unit` explicitly to silence the warning.
4855+
()
48424856
case _ if isUnitExpr =>
48434857
report.warning(PureUnitExpression(original, tree.tpe), original.srcPos)
48444858
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:38:4 ----------------------------------
22
38 | 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:14:2 -----------------------------------------------------------

tests/neg/i13091.check

+8-14
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
-- [E190] Potential Issue Warning: tests/neg/i13091.scala:7:17 ---------------------------------------------------------
2-
7 |def test: Unit = new Foo // error: class Foo is marked @experimental ...
3-
| ^^^^^^^
4-
| Discarded non-Unit value of type Foo. You may want to use `()`.
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
55
|
6-
| longer explanation available when compiling with `-explain`
7-
-- Error: tests/neg/i13091.scala:7:21 ----------------------------------------------------------------------------------
8-
7 |def test: Unit = new Foo // error: class Foo is marked @experimental ...
9-
| ^^^
10-
| class Foo is marked @experimental
11-
|
12-
| Experimental definition may only be used under experimental mode:
13-
| 1. in a definition marked as @experimental, or
14-
| 2. an experimental feature is imported at the package level, or
15-
| 3. compiling with the -experimental compiler flag.
6+
| Experimental definition may only be used under experimental mode:
7+
| 1. in a definition marked as @experimental, or
8+
| 2. an experimental feature is imported at the package level, or
9+
| 3. compiling with the -experimental compiler flag.

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)