@@ -52,16 +52,29 @@ object Inliner {
5252 def inInlineMethod (using Context ): Boolean =
5353 ctx.owner.ownersIterator.exists(_.isInlineMethod)
5454
55- /** Should call to method `meth` be inlined in this context ? */
55+ /** Can a call to method `meth` be inlined? */
5656 def isInlineable (meth : Symbol )(using Context ): Boolean =
5757 meth.is(Inline ) && meth.hasAnnotation(defn.BodyAnnot ) && ! inInlineMethod
5858
5959 /** Should call be inlined in this context? */
60- def isInlineable (tree : Tree )(using Context ): Boolean = tree match {
61- case Block (_, expr) => isInlineable(expr)
62- case _ => isInlineable(tree.symbol) && ! tree.tpe.isInstanceOf [MethodOrPoly ]
60+ def needsInlining (tree : Tree )(using Context ): Boolean = tree match {
61+ case Block (_, expr) => needsInlining(expr)
62+ case _ =>
63+ isInlineable(tree.symbol)
64+ && ! tree.tpe.widenTermRefExpr.isInstanceOf [MethodOrPoly ]
65+ && StagingContext .level == 0
66+ && (
67+ ctx.phase == Phases .inliningPhase
68+ || (ctx.phase == Phases .typerPhase && needsTransparentInlining(tree))
69+ )
70+ && ! ctx.typer.hasInliningErrors
6371 }
6472
73+ private def needsTransparentInlining (tree : Tree )(using Context ): Boolean =
74+ tree.symbol.is(Transparent )
75+ || ctx.mode.is(Mode .ForceInline )
76+ || ctx.settings.YforceInlineWhileTyping .value
77+
6578 /** Try to inline a call to an inline method. Fail with error if the maximal
6679 * inline depth is exceeded.
6780 *
@@ -283,14 +296,15 @@ object Inliner {
283296 assert(tree.symbol == defn.CompiletimeTesting_typeChecks || tree.symbol == defn.CompiletimeTesting_typeCheckErrors )
284297 def stripTyped (t : Tree ): Tree = t match {
285298 case Typed (t2, _) => stripTyped(t2)
299+ case Block (Nil , t2) => stripTyped(t2)
286300 case Inlined (_, Nil , t2) => stripTyped(t2)
287301 case _ => t
288302 }
289303
290304 val Apply (_, codeArg :: Nil ) = tree
291305 val codeArg1 = stripTyped(codeArg.underlying)
292306 val underlyingCodeArg =
293- if Inliner .isInlineable(codeArg1) then stripTyped(Inliner .inlineCall(codeArg1))
307+ if Inliner .isInlineable(codeArg1.symbol ) then stripTyped(Inliner .inlineCall(codeArg1))
294308 else codeArg1
295309
296310 ConstFold (underlyingCodeArg).tpe.widenTermRefExpr match {
@@ -1240,9 +1254,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
12401254 super .ensureAccessible(tpe, superAccess, pos)
12411255 }
12421256
1257+ override def typed (tree : untpd.Tree , pt : Type = WildcardType )(using Context ): Tree =
1258+ val tree1 = super .typed(tree, pt)
1259+ if Inliner .needsInlining(tree1)
1260+ then Inliner .inlineCall(tree1)
1261+ else tree1
1262+
12431263 override def typedIdent (tree : untpd.Ident , pt : Type )(using Context ): Tree =
1244- val tree1 = tryInlineArg(tree.asInstanceOf [tpd.Tree ]) `orElse` super .typedIdent(tree, pt)
1245- inlineIfIsNestedInlineCall(tree1)
1264+ tryInlineArg(tree.asInstanceOf [tpd.Tree ]) `orElse` super .typedIdent(tree, pt)
12461265
12471266 override def typedSelect (tree : untpd.Select , pt : Type )(using Context ): Tree = {
12481267 assert(tree.hasType, tree)
@@ -1254,7 +1273,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
12541273 else
12551274 val res = resMaybeReduced
12561275 ensureAccessible(res.tpe, tree.qualifier.isInstanceOf [untpd.Super ], tree.srcPos)
1257- inlineIfIsNestedInlineCall( res)
1276+ res
12581277 }
12591278
12601279 override def typedIf (tree : untpd.If , pt : Type )(using Context ): Tree =
@@ -1287,18 +1306,18 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
12871306 val res = constToLiteral(betaReduce(super .typedApply(tree, pt))) match {
12881307 case res : Apply if res.symbol == defn.QuotedRuntime_exprSplice
12891308 && level == 0
1290- && ! suppressInline =>
1309+ && ! hasInliningErrors =>
12911310 val expanded = expandMacro(res.args.head, tree.span)
12921311 typedExpr(expanded) // Inline calls and constant fold code generated by the macro
12931312 case res =>
1294- inlineIfIsNestedInlineCall( res)
1313+ res
12951314 }
12961315 if res.symbol == defn.QuotedRuntime_exprQuote then
12971316 ctx.compilationUnit.needsQuotePickling = true
12981317 res
12991318
13001319 override def typedTypeApply (tree : untpd.TypeApply , pt : Type )(using Context ): Tree =
1301- inlineIfIsNestedInlineCall( constToLiteral(betaReduce(super .typedTypeApply(tree, pt) )))
1320+ constToLiteral(betaReduce(super .typedTypeApply(tree, pt)))
13021321
13031322 override def typedMatch (tree : untpd.Match , pt : Type )(using Context ): Tree =
13041323 val tree1 =
@@ -1354,19 +1373,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
13541373
13551374 override def newLikeThis : Typer = new InlineTyper (initialErrorCount)
13561375
1357- /** Suppress further inlining if this inline typer has already issued errors */
1358- override def suppressInline (using Context ) =
1359- ctx.reporter.errorCount > initialErrorCount || super .suppressInline
1360-
1361- private def inlineIfIsNestedInlineCall (tree : Tree )(using Context ): Tree =
1362- if
1363- ! suppressInline &&
1364- ! tree.tpe.widenTermRefExpr.isInstanceOf [MethodOrPoly ] &&
1365- Inliner .isInlineable(tree) &&
1366- StagingContext .level == 0 &&
1367- (ctx.isAfterTyper || tree.symbol.is(Transparent ) || ctx.mode.is(Mode .ForceInline ) || ctx.settings.YforceInlineWhileTyping .value)
1368- then Inliner .inlineCall(tree)
1369- else tree
1376+ /** True if this inline typer has already issued errors */
1377+ override def hasInliningErrors (using Context ) = ctx.reporter.errorCount > initialErrorCount
1378+
13701379 }
13711380
13721381 /** Drop any side-effect-free bindings that are unused in expansion or other reachable bindings.
0 commit comments