@@ -35,7 +35,7 @@ import util.common.*
3535import util .{Property , SimpleIdentityMap , SrcPos }
3636import Applications .{tupleComponentTypes , wrapDefs , defaultArgument }
3737
38- import collection .mutable
38+ import collection .mutable , mutable . ListBuffer
3939import Implicits .*
4040import util .Stats .record
4141import config .Printers .{gadts , typr }
@@ -207,7 +207,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
207207 * a reference for `m` is searched. `null` in all other situations.
208208 */
209209 def findRef (name : Name , pt : Type , required : FlagSet , excluded : FlagSet , pos : SrcPos ,
210- altImports : mutable. ListBuffer [TermRef ] | Null = null )(using Context ): Type = {
210+ altImports : ListBuffer [TermRef ] | Null = null )(using Context ): Type = {
211211 val refctx = ctx
212212 val noImports = ctx.mode.is(Mode .InPackageClauseName )
213213 def suppressErrors = excluded.is(ConstructorProxy )
@@ -1124,7 +1124,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
11241124 record(" typedNumber" )
11251125 val digits = tree.digits
11261126 val target = pt.dealias
1127- def lit (value : Any ) = Literal (Constant (value)).withSpan(tree.span)
1127+ def lit (value : Any ) = Literal (Constant (value)).withSpan(tree.span).withAttachmentsFrom(tree)
11281128 try {
11291129 // Special case primitive numeric types
11301130 if (target.isRef(defn.IntClass ) ||
@@ -1174,7 +1174,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
11741174 }
11751175 var app : untpd.Tree = untpd.Apply (fromDigits, firstArg :: otherArgs)
11761176 if (ctx.mode.is(Mode .Pattern )) app = untpd.Block (Nil , app)
1177- return typed(app, pt)
1177+ return typed(app, pt).withAttachmentsFrom(tree)
11781178 case _ =>
11791179 }
11801180 // Otherwise convert to Int or Double according to digits format
@@ -3501,7 +3501,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
35013501 else {
35023502 val app = typedApply(desugar.binop(l, op, r).withAttachmentsFrom(tree), pt)
35033503 if op.name.isRightAssocOperatorName && ! ctx.mode.is(Mode .QuotedExprPattern ) then
3504- val defs = new mutable. ListBuffer [Tree ]
3504+ val defs = ListBuffer .empty [Tree ]
35053505 def lift (app : Tree ): Tree = (app : @ unchecked) match
35063506 case Apply (fn, args) =>
35073507 if (app.tpe.isError) app
@@ -3801,7 +3801,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38013801 trees mapconserve (typed(_))
38023802
38033803 def typedStats (stats : List [untpd.Tree ], exprOwner : Symbol )(using Context ): (List [Tree ], Context ) = {
3804- val buf = new mutable. ListBuffer [Tree ]
3804+ val buf = ListBuffer .empty [Tree ]
38053805 var enumContexts : SimpleIdentityMap [Symbol , Context ] = SimpleIdentityMap .empty
38063806 val initialNotNullInfos = ctx.notNullInfos
38073807 // A map from `enum` symbols to the contexts enclosing their definitions
@@ -3845,7 +3845,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38453845 traverse(xtree :: rest)
38463846 case stat :: rest =>
38473847 val stat1 = typed(stat)(using ctx.exprContext(stat, exprOwner))
3848- if ! Linter .warnOnInterestingResultInStatement(stat1) then checkStatementPurity(stat1)(stat, exprOwner)
3848+ if ! Linter .warnOnInterestingResultInStatement(stat1) then
3849+ checkStatementPurity(stat1)(stat, exprOwner, isUnitExpr = false )
38493850 buf += stat1
38503851 traverse(rest)(using stat1.nullableContext)
38513852 case nil =>
@@ -4052,7 +4053,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
40524053 def selectionProto = SelectionProto (tree.name, mbrProto, compat, privateOK = inSelect, tree.nameSpan)
40534054
40544055 def tryExtension (using Context ): Tree =
4055- val altImports = new mutable. ListBuffer [TermRef ]()
4056+ val altImports = ListBuffer .empty [TermRef ]
40564057 findRef(tree.name, WildcardType , ExtensionMethod , EmptyFlags , qual.srcPos, altImports) match
40574058 case ref : TermRef =>
40584059 def tryExtMethod (ref : TermRef )(using Context ) =
@@ -4061,7 +4062,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
40614062 tryExtMethod(ref)
40624063 else
40634064 // Try all possible imports and collect successes and failures
4064- val successes, failures = new mutable. ListBuffer [(Tree , TyperState )]
4065+ val successes, failures = ListBuffer .empty [(Tree , TyperState )]
40654066 for alt <- ref :: altImports.toList do
40664067 val nestedCtx = ctx.fresh.setNewTyperState()
40674068 val app = tryExtMethod(alt)(using nestedCtx)
@@ -4719,22 +4720,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
47194720 return readapt(tree.cast(captured))
47204721
47214722 // drop type if prototype is Unit
4722- if (pt isRef defn.UnitClass ) {
4723+ if pt. isRef( defn.UnitClass ) then
47234724 // local adaptation makes sure every adapted tree conforms to its pt
47244725 // so will take the code path that decides on inlining
47254726 val tree1 = adapt(tree, WildcardType , locked)
47264727 checkStatementPurity(tree1)(tree, ctx.owner, isUnitExpr = true )
4727-
4728- if ctx.settings.Whas .valueDiscard
4729- && ! ctx.isAfterTyper
4730- && ! tree.isInstanceOf [Inlined ]
4731- && ! isThisTypeResult(tree)
4732- && ! isAscribedToUnit(tree)
4733- then
4734- report.warning(ValueDiscarding (tree.tpe), tree.srcPos)
4735-
4728+ checkValueDiscard(tree)
47364729 return tpd.Block (tree1 :: Nil , unitLiteral)
4737- }
47384730
47394731 // convert function literal to SAM closure
47404732 tree match {
@@ -4992,11 +4984,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
49924984 typedExpr(cmp, defn.BooleanType )
49934985 case _ =>
49944986
4995- private def checkStatementPurity (tree : tpd.Tree )(original : untpd.Tree , exprOwner : Symbol , isUnitExpr : Boolean = false )(using Context ): Unit =
4987+ private def checkStatementPurity (tree : tpd.Tree )(original : untpd.Tree , exprOwner : Symbol , isUnitExpr : Boolean )(using Context ): Unit =
4988+ inline def isPureNotInlinedUnit = tree match
4989+ case Inlined (_, Nil , Literal (k)) if k.tag == UnitTag => false // assert(2 + 2 == 4)
4990+ case tree => isPureExpr(tree)
49964991 if ! tree.tpe.isErroneous
49974992 && ! ctx.isAfterTyper
4998- && ! tree.isInstanceOf [Inlined ]
4999- && isPureExpr(tree)
4993+ && isPureNotInlinedUnit
50004994 && ! isSelfOrSuperConstrCall(tree)
50014995 then tree match
50024996 case closureDef(meth)
@@ -5010,13 +5004,26 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
50105004 // sometimes we do not have the original anymore and use the transformed tree instead.
50115005 // But taken together, the two criteria are quite accurate.
50125006 missingArgs(tree, tree.tpe.widen)
5013- case _ if tree.hasAttachment(AscribedToUnit ) =>
5014- // The tree was ascribed to `Unit` explicitly to silence the warning.
5015- ()
5016- case _ if isUnitExpr =>
5017- report.warning(PureUnitExpression (original, tree.tpe), original.srcPos)
5018- case _ =>
5019- report.warning(PureExpressionInStatementPosition (original, exprOwner), original.srcPos)
5007+ case tree =>
5008+ val warnable = tree match
5009+ case inlined : Inlined => inlined.expansion
5010+ case tree => tree
5011+ // Check if the tree was ascribed to `Unit` explicitly to silence the warning.
5012+ if ! isThisTypeResult(warnable) && ! isAscribedToUnit(warnable) then
5013+ val msg =
5014+ if isUnitExpr then
5015+ PureUnitExpression (original, warnable.tpe)
5016+ else
5017+ PureExpressionInStatementPosition (original, exprOwner)
5018+ report.warning(msg, original.srcPos)
5019+
5020+ private def checkValueDiscard (tree : tpd.Tree )(using Context ): Unit =
5021+ if ctx.settings.Whas .valueDiscard && ! ctx.isAfterTyper then
5022+ val warnable = tree match
5023+ case inlined : Inlined => inlined.expansion
5024+ case tree => tree
5025+ if ! isThisTypeResult(warnable) && ! isAscribedToUnit(warnable) then
5026+ report.warning(ValueDiscarding (warnable.tpe), tree.srcPos)
50205027
50215028 /** Types the body Scala 2 macro declaration `def f = macro <body>` */
50225029 protected def typedScala2MacroBody (call : untpd.Tree )(using Context ): Tree =
0 commit comments