@@ -38,15 +38,20 @@ object Inliner {
38
38
def hasBodyToInline (sym : SymDenotation )(implicit ctx : Context ): Boolean =
39
39
sym.isInlineMethod && sym.hasAnnotation(defn.BodyAnnot )
40
40
41
- /** The body to inline for method `sym`.
41
+ /** The body to inline for method `sym`, or `EmptyTree` if none exists.
42
+ * Note: definitions coming from Scala2x class files might be `@forceInline`,
43
+ * but still lack that body.
42
44
* @pre hasBodyToInline(sym)
43
45
*/
44
46
def bodyToInline (sym : SymDenotation )(implicit ctx : Context ): Tree =
45
- sym.unforcedAnnotation(defn.BodyAnnot ).get.tree
47
+ if (sym.isInlineMethod && sym.hasAnnotation(defn.BodyAnnot ))
48
+ sym.getAnnotation(defn.BodyAnnot ).get.tree
49
+ else
50
+ EmptyTree
46
51
47
52
/** Should call to method `meth` be inlined in this context? */
48
53
def isInlineable (meth : Symbol )(implicit ctx : Context ): Boolean =
49
- meth.is(Inline ) && hasBodyToInline(meth) && ! ctx.inInlineMethod
54
+ meth.is(Inline ) && ! ctx.inInlineMethod && ! bodyToInline(meth).isEmpty
50
55
51
56
/** Should call be inlined in this context? */
52
57
def isInlineable (tree : Tree )(implicit ctx : Context ): Boolean = tree match {
@@ -105,8 +110,7 @@ object Inliner {
105
110
cpy.Block (tree)(bindings.toList, inlineCall(tree1))
106
111
else if (enclosingInlineds.length < ctx.settings.XmaxInlines .value) {
107
112
val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
108
- if (ctx.reporter.hasErrors) tree
109
- else new Inliner (tree, body).inlined(tree.sourcePos)
113
+ new Inliner (tree, body).inlined(tree.sourcePos)
110
114
}
111
115
else
112
116
errorTree(
@@ -204,7 +208,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
204
208
private val inlineCallPrefix =
205
209
qualifier(methPart).orElse(This (inlinedMethod.enclosingClass.asClass))
206
210
207
- inlining.println(" -----------------------\n Inlining $call\n With RHS $rhsToInline" )
211
+ inlining.println(i " ----------------------- \n Inlining $call\n With RHS $rhsToInline" )
208
212
209
213
// Make sure all type arguments to the call are fully determined
210
214
for (targ <- callTypeArgs) fullyDefinedType(targ.tpe, " inlined type argument" , targ.span)
@@ -421,7 +425,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
421
425
// Compute bindings for all this-proxies, appending them to bindingsBuf
422
426
computeThisBindings()
423
427
424
- val inlineTyper = new InlineTyper
428
+ val inlineTyper = new InlineTyper (ctx.reporter.errorCount)
425
429
426
430
val inlineCtx = inlineContext(call).fresh.setTyper(inlineTyper).setNewScope
427
431
@@ -986,7 +990,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
986
990
* 4. Make sure inlined code is type-correct.
987
991
* 5. Make sure that the tree's typing is idempotent (so that future -Ycheck passes succeed)
988
992
*/
989
- class InlineTyper extends ReTyper {
993
+ class InlineTyper ( initialErrorCount : Int ) extends ReTyper {
990
994
import reducer ._
991
995
992
996
override def ensureAccessible (tpe : Type , superAccess : Boolean , pos : SourcePosition )(implicit ctx : Context ): Type = {
@@ -1033,7 +1037,11 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
1033
1037
1034
1038
override def typedApply (tree : untpd.Apply , pt : Type )(implicit ctx : Context ): Tree =
1035
1039
constToLiteral(betaReduce(super .typedApply(tree, pt))) match {
1036
- case res : Apply if res.symbol == defn.InternalQuoted_exprSplice && level == 0 && call.symbol.is(Macro ) =>
1040
+ case res : Apply
1041
+ if res.symbol == defn.InternalQuoted_exprSplice &&
1042
+ level == 0 &&
1043
+ call.symbol.is(Macro ) &&
1044
+ ! suppressInline =>
1037
1045
expandMacro(res.args.head, tree.span)
1038
1046
case res => res
1039
1047
}
@@ -1082,7 +1090,11 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
1082
1090
}
1083
1091
}
1084
1092
1085
- override def newLikeThis : Typer = new InlineTyper
1093
+ override def newLikeThis : Typer = new InlineTyper (initialErrorCount)
1094
+
1095
+ /** Suppress further inlining if this inline typer has already issued errors */
1096
+ override def suppressInline given (ctx : Context ) =
1097
+ ctx.reporter.errorCount > initialErrorCount || super .suppressInline
1086
1098
}
1087
1099
1088
1100
/** Drop any side-effect-free bindings that are unused in expansion or other reachable bindings.
@@ -1202,8 +1214,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
1202
1214
}
1203
1215
}
1204
1216
val normalizedSplice = inlinedNormailizer.transform(evaluatedSplice)
1205
-
1206
- if (ctx.reporter.hasErrors) EmptyTree
1217
+ if (normalizedSplice.isEmpty) normalizedSplice
1207
1218
else normalizedSplice.withSpan(span)
1208
1219
}
1209
1220
}
0 commit comments