@@ -52,16 +52,29 @@ object Inliner {
52
52
def inInlineMethod (using Context ): Boolean =
53
53
ctx.owner.ownersIterator.exists(_.isInlineMethod)
54
54
55
- /** Should call to method `meth` be inlined in this context ? */
55
+ /** Can a call to method `meth` be inlined? */
56
56
def isInlineable (meth : Symbol )(using Context ): Boolean =
57
57
meth.is(Inline ) && meth.hasAnnotation(defn.BodyAnnot ) && ! inInlineMethod
58
58
59
59
/** 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
63
71
}
64
72
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
+
65
78
/** Try to inline a call to an inline method. Fail with error if the maximal
66
79
* inline depth is exceeded.
67
80
*
@@ -283,14 +296,15 @@ object Inliner {
283
296
assert(tree.symbol == defn.CompiletimeTesting_typeChecks || tree.symbol == defn.CompiletimeTesting_typeCheckErrors )
284
297
def stripTyped (t : Tree ): Tree = t match {
285
298
case Typed (t2, _) => stripTyped(t2)
299
+ case Block (Nil , t2) => stripTyped(t2)
286
300
case Inlined (_, Nil , t2) => stripTyped(t2)
287
301
case _ => t
288
302
}
289
303
290
304
val Apply (_, codeArg :: Nil ) = tree
291
305
val codeArg1 = stripTyped(codeArg.underlying)
292
306
val underlyingCodeArg =
293
- if Inliner .isInlineable(codeArg1) then stripTyped(Inliner .inlineCall(codeArg1))
307
+ if Inliner .isInlineable(codeArg1.symbol ) then stripTyped(Inliner .inlineCall(codeArg1))
294
308
else codeArg1
295
309
296
310
ConstFold (underlyingCodeArg).tpe.widenTermRefExpr match {
@@ -1240,9 +1254,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1240
1254
super .ensureAccessible(tpe, superAccess, pos)
1241
1255
}
1242
1256
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
+
1243
1263
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)
1246
1265
1247
1266
override def typedSelect (tree : untpd.Select , pt : Type )(using Context ): Tree = {
1248
1267
assert(tree.hasType, tree)
@@ -1254,7 +1273,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1254
1273
else
1255
1274
val res = resMaybeReduced
1256
1275
ensureAccessible(res.tpe, tree.qualifier.isInstanceOf [untpd.Super ], tree.srcPos)
1257
- inlineIfIsNestedInlineCall( res)
1276
+ res
1258
1277
}
1259
1278
1260
1279
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) {
1287
1306
val res = constToLiteral(betaReduce(super .typedApply(tree, pt))) match {
1288
1307
case res : Apply if res.symbol == defn.QuotedRuntime_exprSplice
1289
1308
&& level == 0
1290
- && ! suppressInline =>
1309
+ && ! hasInliningErrors =>
1291
1310
val expanded = expandMacro(res.args.head, tree.span)
1292
1311
typedExpr(expanded) // Inline calls and constant fold code generated by the macro
1293
1312
case res =>
1294
- inlineIfIsNestedInlineCall( res)
1313
+ res
1295
1314
}
1296
1315
if res.symbol == defn.QuotedRuntime_exprQuote then
1297
1316
ctx.compilationUnit.needsQuotePickling = true
1298
1317
res
1299
1318
1300
1319
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)))
1302
1321
1303
1322
override def typedMatch (tree : untpd.Match , pt : Type )(using Context ): Tree =
1304
1323
val tree1 =
@@ -1354,19 +1373,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1354
1373
1355
1374
override def newLikeThis : Typer = new InlineTyper (initialErrorCount)
1356
1375
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
+
1370
1379
}
1371
1380
1372
1381
/** Drop any side-effect-free bindings that are unused in expansion or other reachable bindings.
0 commit comments