@@ -38,15 +38,20 @@ object Inliner {
3838 def hasBodyToInline (sym : SymDenotation )(implicit ctx : Context ): Boolean =
3939 sym.isInlineMethod && sym.hasAnnotation(defn.BodyAnnot )
4040
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.
4244 * @pre hasBodyToInline(sym)
4345 */
4446 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
4651
4752 /** Should call to method `meth` be inlined in this context? */
4853 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
5055
5156 /** Should call be inlined in this context? */
5257 def isInlineable (tree : Tree )(implicit ctx : Context ): Boolean = tree match {
@@ -105,8 +110,7 @@ object Inliner {
105110 cpy.Block (tree)(bindings.toList, inlineCall(tree1))
106111 else if (enclosingInlineds.length < ctx.settings.XmaxInlines .value) {
107112 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)
110114 }
111115 else
112116 errorTree(
@@ -204,7 +208,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
204208 private val inlineCallPrefix =
205209 qualifier(methPart).orElse(This (inlinedMethod.enclosingClass.asClass))
206210
207- inlining.println(" -----------------------\n Inlining $call\n With RHS $rhsToInline" )
211+ inlining.println(i " ----------------------- \n Inlining $call\n With RHS $rhsToInline" )
208212
209213 // Make sure all type arguments to the call are fully determined
210214 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) {
421425 // Compute bindings for all this-proxies, appending them to bindingsBuf
422426 computeThisBindings()
423427
424- val inlineTyper = new InlineTyper
428+ val inlineTyper = new InlineTyper (ctx.reporter.errorCount)
425429
426430 val inlineCtx = inlineContext(call).fresh.setTyper(inlineTyper).setNewScope
427431
@@ -986,7 +990,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
986990 * 4. Make sure inlined code is type-correct.
987991 * 5. Make sure that the tree's typing is idempotent (so that future -Ycheck passes succeed)
988992 */
989- class InlineTyper extends ReTyper {
993+ class InlineTyper ( initialErrorCount : Int ) extends ReTyper {
990994 import reducer ._
991995
992996 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) {
10331037
10341038 override def typedApply (tree : untpd.Apply , pt : Type )(implicit ctx : Context ): Tree =
10351039 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 =>
10371045 expandMacro(res.args.head, tree.span)
10381046 case res => res
10391047 }
@@ -1082,7 +1090,11 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
10821090 }
10831091 }
10841092
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
10861098 }
10871099
10881100 /** 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) {
12021214 }
12031215 }
12041216 val normalizedSplice = inlinedNormailizer.transform(evaluatedSplice)
1205-
1206- if (ctx.reporter.hasErrors) EmptyTree
1217+ if (normalizedSplice.isEmpty) normalizedSplice
12071218 else normalizedSplice.withSpan(span)
12081219 }
12091220}
0 commit comments