@@ -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 _ =>
0 commit comments