From b36658d257115329cfe25b794685bc85ea1cfc22 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 4 Apr 2016 11:51:38 +0200 Subject: Remove dead code in the optimizer related to trait impl classes --- .../scala/tools/nsc/backend/jvm/BCodeHelpers.scala | 11 +-- .../scala/tools/nsc/backend/jvm/BTypes.scala | 27 +----- .../tools/nsc/backend/jvm/opt/CallGraph.scala | 31 +++--- .../nsc/backend/jvm/opt/ClosureOptimizer.scala | 1 - .../nsc/backend/jvm/opt/InlineInfoAttribute.scala | 46 ++++----- .../scala/tools/nsc/backend/jvm/opt/Inliner.scala | 107 --------------------- .../nsc/backend/jvm/opt/InlinerHeuristics.scala | 6 +- 7 files changed, 41 insertions(+), 188 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index a2ccce9d21..271146f623 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -247,14 +247,6 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { * Build the [[InlineInfo]] for a class symbol. */ def buildInlineInfoFromClassSymbol(classSym: Symbol, classSymToInternalName: Symbol => InternalName, methodSymToDescriptor: Symbol => String): InlineInfo = { - val traitSelfType = if (classSym.isTrait) { - // The mixin phase uses typeOfThis for the self parameter in implementation class methods. - val selfSym = classSym.typeOfThis.typeSymbol - if (selfSym != classSym) Some(classSymToInternalName(selfSym)) else None - } else { - None - } - val isEffectivelyFinal = classSym.isEffectivelyFinal val sam = { @@ -291,7 +283,6 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { val info = MethodInlineInfo( effectivelyFinal = effectivelyFinal, - traitMethodWithStaticImplementation = false, annotatedInline = methodSym.hasAnnotation(ScalaInlineClass), annotatedNoInline = methodSym.hasAnnotation(ScalaNoInlineClass) ) @@ -299,7 +290,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } }).toMap - InlineInfo(traitSelfType, isEffectivelyFinal, sam, methodInlineInfos, warning) + InlineInfo(isEffectivelyFinal, sam, methodInlineInfos, warning) } /* diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala index c3f6399901..192c2ee14e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala @@ -255,13 +255,11 @@ abstract class BTypes { val methodInfos = classNode.methods.asScala.map(methodNode => { val info = MethodInlineInfo( effectivelyFinal = BytecodeUtils.isFinalMethod(methodNode), - traitMethodWithStaticImplementation = false, annotatedInline = false, annotatedNoInline = false) (methodNode.name + methodNode.desc, info) }).toMap InlineInfo( - traitImplClassSelfType = None, isEffectivelyFinal = BytecodeUtils.isFinalClass(classNode), sam = inlinerHeuristics.javaSam(classNode.name), methodInfos = methodInfos, @@ -1139,22 +1137,8 @@ object BTypes { * Note that this class should contain information that can only be obtained from the ClassSymbol. * Information that can be computed from the ClassNode should be added to the call graph instead. * - * @param traitImplClassSelfType `Some(tp)` if this InlineInfo describes a trait, and the `self` - * parameter type of the methods in the implementation class is not - * the trait itself. Example: - * trait T { self: U => def f = 1 } - * Generates something like: - * class T$class { static def f(self: U) = 1 } - * - * In order to inline a trat method call, the INVOKEINTERFACE is - * rewritten to an INVOKESTATIC of the impl class, so we need the - * self type (U) to get the right signature. - * - * `None` if the self type is the interface type, or if this - * InlineInfo does not describe a trait. - * * @param isEffectivelyFinal True if the class cannot have subclasses: final classes, module - * classes, trait impl classes. + * classes. * * @param sam If this class is a SAM type, the SAM's "$name$descriptor". * @@ -1166,26 +1150,21 @@ object BTypes { * InlineInfo, for example if some classfile could not be found on * the classpath. This warning can be reported later by the inliner. */ - final case class InlineInfo(traitImplClassSelfType: Option[InternalName], - isEffectivelyFinal: Boolean, + final case class InlineInfo(isEffectivelyFinal: Boolean, sam: Option[String], methodInfos: Map[String, MethodInlineInfo], warning: Option[ClassInlineInfoWarning]) - val EmptyInlineInfo = InlineInfo(None, false, None, Map.empty, None) + val EmptyInlineInfo = InlineInfo(false, None, Map.empty, None) /** * Metadata about a method, used by the inliner. * * @param effectivelyFinal True if the method cannot be overridden (in Scala) - * @param traitMethodWithStaticImplementation True if the method is an interface method method of - * a trait method and has a static counterpart in the - * implementation class. * @param annotatedInline True if the method is annotated `@inline` * @param annotatedNoInline True if the method is annotated `@noinline` */ final case class MethodInlineInfo(effectivelyFinal: Boolean, - traitMethodWithStaticImplementation: Boolean, annotatedInline: Boolean, annotatedNoInline: Boolean) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala index 3267b9b5df..5f06e13560 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala @@ -132,16 +132,16 @@ class CallGraph[BT <: BTypes](val btypes: BT) { (declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)] } yield { val declarationClassBType = classBTypeFromClassNode(declarationClassNode) - val CallsiteInfo(safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call, source) + val info = analyzeCallsite(method, declarationClassBType, call, source) + import info._ Callee( callee = method, calleeDeclarationClass = declarationClassBType, safeToInline = safeToInline, - safeToRewrite = false, canInlineFromSource = canInlineFromSource, annotatedInline = annotatedInline, annotatedNoInline = annotatedNoInline, - samParamTypes = samParamTypes, + samParamTypes = info.samParamTypes, calleeInfoWarning = warning) } @@ -256,7 +256,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { /** * Just a named tuple used as return type of `analyzeCallsite`. */ - private case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean, + private case class CallsiteInfo(safeToInline: Boolean, canInlineFromSource: Boolean, annotatedInline: Boolean, annotatedNoInline: Boolean, samParamTypes: IntMap[ClassBType], warning: Option[CalleeInfoWarning]) @@ -300,16 +300,12 @@ class CallGraph[BT <: BTypes](val btypes: BT) { receiverType.info.orThrow.inlineInfo.isEffectivelyFinal // (1) } - val isRewritableTraitCall = false - val warning = calleeDeclarationClassBType.info.orThrow.inlineInfo.warning.map( MethodInlineInfoIncomplete(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, _)) // (1) For invocations of final trait methods, the callee isStaticallyResolved but also // abstract. Such a callee is not safe to inline - it needs to be re-written to the // static impl method first (safeToRewrite). - // (2) Final trait methods can be rewritten from the interface to the static implementation - // method to enable inlining. CallsiteInfo( safeToInline = canInlineFromSource && @@ -318,7 +314,6 @@ class CallGraph[BT <: BTypes](val btypes: BT) { !BytecodeUtils.isConstructor(calleeMethodNode) && !BytecodeUtils.isNativeMethod(calleeMethodNode) && !BytecodeUtils.hasCallerSensitiveAnnotation(calleeMethodNode), - safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2) canInlineFromSource = canInlineFromSource, annotatedInline = methodInlineInfo.annotatedInline, annotatedNoInline = methodInlineInfo.annotatedNoInline, @@ -327,12 +322,12 @@ class CallGraph[BT <: BTypes](val btypes: BT) { case None => val warning = MethodInlineInfoMissing(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, calleeDeclarationClassBType.info.orThrow.inlineInfo.warning) - CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning)) + CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning)) } } catch { case Invalid(noInfo: NoClassBTypeInfo) => val warning = MethodInlineInfoError(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, noInfo) - CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning)) + CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning)) } } @@ -387,20 +382,18 @@ class CallGraph[BT <: BTypes](val btypes: BT) { * @param calleeDeclarationClass The class in which the callee is declared * @param safeToInline True if the callee can be safely inlined: it cannot be overridden, * and the inliner settings (project / global) allow inlining it. - * @param safeToRewrite True if the callee is the interface method of a concrete trait method - * that can be safely re-written to the static implementation method. * @param annotatedInline True if the callee is annotated @inline * @param annotatedNoInline True if the callee is annotated @noinline * @param samParamTypes A map from parameter positions to SAM parameter types * @param calleeInfoWarning An inliner warning if some information was not available while * gathering the information about this callee. */ - final case class Callee(callee: MethodNode, calleeDeclarationClass: ClassBType, - safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean, - annotatedInline: Boolean, annotatedNoInline: Boolean, - samParamTypes: IntMap[ClassBType], - calleeInfoWarning: Option[CalleeInfoWarning]) { - assert(!(safeToInline && safeToRewrite), s"A callee of ${callee.name} can be either safeToInline or safeToRewrite, but not both.") + final case class Callee( + callee: MethodNode, calleeDeclarationClass: btypes.ClassBType, + safeToInline: Boolean, canInlineFromSource: Boolean, + annotatedInline: Boolean, annotatedNoInline: Boolean, + samParamTypes: IntMap[btypes.ClassBType], + calleeInfoWarning: Option[CalleeInfoWarning]) { override def toString = s"Callee($calleeDeclarationClass.${callee.name})" } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala index 4935b9d1a0..fef15bcf9a 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala @@ -363,7 +363,6 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) { callee = bodyMethodNode, calleeDeclarationClass = bodyDeclClassType, safeToInline = canInlineFromSource, - safeToRewrite = false, // the lambda body method is not a trait interface method canInlineFromSource = canInlineFromSource, annotatedInline = false, annotatedNoInline = false, diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala index c885a29e16..079a9eec9b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala @@ -27,7 +27,7 @@ import scala.tools.nsc.backend.jvm.BackendReporting.UnknownScalaInlineInfoVersio * In principle we could encode the InlineInfo into a Java annotation (instead of a classfile attribute). * However, an attribute allows us to save many bits. In particular, note that the strings in an * InlineInfo are serialized as references to constants in the constant pool, and those strings - * (traitImplClassSelfType, method names, method signatures) would exist in there anyway. So the + * (method names, method signatures) would exist in there anyway. So the * ScalaInlineAttribute remains relatively compact. */ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineInfoAttribute.attributeName) { @@ -48,15 +48,11 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI result.putByte(InlineInfoAttribute.VERSION) var finalSelfSam = 0 - if (inlineInfo.isEffectivelyFinal) finalSelfSam |= 1 - if (inlineInfo.traitImplClassSelfType.isDefined) finalSelfSam |= 2 - if (inlineInfo.sam.isDefined) finalSelfSam |= 4 + if (inlineInfo.isEffectivelyFinal) finalSelfSam |= 1 + // finalSelfSam |= 2 // no longer written + if (inlineInfo.sam.isDefined) finalSelfSam |= 4 result.putByte(finalSelfSam) - for (selfInternalName <- inlineInfo.traitImplClassSelfType) { - result.putShort(cw.newUTF8(selfInternalName)) - } - for (samNameDesc <- inlineInfo.sam) { val (name, desc) = samNameDesc.span(_ != '(') result.putShort(cw.newUTF8(name)) @@ -75,10 +71,10 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI result.putShort(cw.newUTF8(desc)) var inlineInfo = 0 - if (info.effectivelyFinal) inlineInfo |= 1 - if (info.traitMethodWithStaticImplementation) inlineInfo |= 2 - if (info.annotatedInline) inlineInfo |= 4 - if (info.annotatedNoInline) inlineInfo |= 8 + if (info.effectivelyFinal) inlineInfo |= 1 + // inlineInfo |= 2 // no longer written + if (info.annotatedInline) inlineInfo |= 4 + if (info.annotatedNoInline) inlineInfo |= 8 result.putByte(inlineInfo) } @@ -106,10 +102,7 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI val hasSelf = (finalSelfSam & 2) != 0 val hasSam = (finalSelfSam & 4) != 0 - val self = if (!hasSelf) None else { - val selfName = nextUTF8() - Some(selfName) - } + if (hasSelf) nextUTF8() // no longer used val sam = if (!hasSam) None else { val name = nextUTF8() @@ -123,14 +116,14 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI val desc = nextUTF8() val inlineInfo = nextByte() - val isFinal = (inlineInfo & 1) != 0 - val traitMethodWithStaticImplementation = (inlineInfo & 2) != 0 - val isInline = (inlineInfo & 4) != 0 - val isNoInline = (inlineInfo & 8) != 0 - (name + desc, MethodInlineInfo(isFinal, traitMethodWithStaticImplementation, isInline, isNoInline)) + val isFinal = (inlineInfo & 1) != 0 + // val traitMethodWithStaticImplementation = (inlineInfo & 2) != 0 // no longer used + val isInline = (inlineInfo & 4) != 0 + val isNoInline = (inlineInfo & 8) != 0 + (name + desc, MethodInlineInfo(isFinal, isInline, isNoInline)) }).toMap - InlineInfoAttribute(InlineInfo(self, isFinal, sam, infos, None)) + InlineInfoAttribute(InlineInfo(isFinal, sam, infos, None)) } else { val msg = UnknownScalaInlineInfoVersion(cr.getClassName, version) InlineInfoAttribute(BTypes.EmptyInlineInfo.copy(warning = Some(msg))) @@ -140,6 +133,13 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI object InlineInfoAttribute { /** + * Notes: + * - `traitImplClassSelfType` is no longer emitted, `hasTraitImplClassSelfType` is always emitted + * as 0. Similarly, `traitMethodWithStaticImplementation` is always emitted 0. + * - When reading an existing attribute where `hasTraitImplClassSelfType` is 1, the + * `traitImplClassSelfType` is ignored. Also the value of `traitMethodWithStaticImplementation` + * is ignored. + * * [u1] version * [u1] isEffectivelyFinal (<< 0), hasTraitImplClassSelfType (<< 1), hasSam (<< 2) * [u2]? traitImplClassSelfType (reference) @@ -159,4 +159,4 @@ object InlineInfoAttribute { * In order to instruct the ASM framework to de-serialize the ScalaInlineInfo attribute, we need * to pass a prototype instance when running the class reader. */ -object InlineInfoAttributePrototype extends InlineInfoAttribute(InlineInfo(null, false, null, null, null)) +object InlineInfoAttributePrototype extends InlineInfoAttribute(InlineInfo(false, null, null, null)) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala index 32106614e3..a0ef74b46a 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -27,8 +27,6 @@ class Inliner[BT <: BTypes](val btypes: BT) { import backendUtils._ def runInliner(): Unit = { -// rewriteFinalTraitMethodInvocations() - for (request <- collectAndOrderInlineRequests) { val Right(callee) = request.callsite.callee // collectAndOrderInlineRequests returns callsites with a known callee @@ -70,111 +68,6 @@ class Inliner[BT <: BTypes](val btypes: BT) { } } - // Rewriting final trait method callsites to the implementation class enables inlining. - def rewriteFinalTraitMethodInvocations(): Unit = { - // Collect callsites to rewrite before actually rewriting anything. This prevents changing the - // `callsties` map while iterating it. - val toRewrite = mutable.ArrayBuffer.empty[Callsite] - for (css <- callsites.valuesIterator; cs <- css.valuesIterator if doRewriteTraitCallsite(cs)) toRewrite += cs - toRewrite foreach rewriteFinalTraitMethodInvocation - } - - /** - * True for statically resolved trait callsites that should be rewritten to the static implementation method. - */ - def doRewriteTraitCallsite(callsite: Callsite) = callsite.callee match { - case Right(callee) => callee.safeToRewrite - case _ => false - } - - /** - * Rewrite the INVOKEINTERFACE callsite of a final trait method invocation to INVOKESTATIC of the - * corresponding method in the implementation class. This enables inlining final trait methods. - * - * In a final trait method callsite, the callee is safeToInline and the callee method is abstract - * (the receiver type is the interface, so the method is abstract). - */ - def rewriteFinalTraitMethodInvocation(callsite: Callsite): Unit = { - // The analyzer used below needs to have a non-null frame for the callsite instruction - localOpt.minimalRemoveUnreachableCode(callsite.callsiteMethod, callsite.callsiteClass.internalName) - - // If the callsite was eliminated by DCE, do nothing. - if (!callGraph.containsCallsite(callsite)) return - - val Right(Callee(callee, calleeDeclarationClass, _, _, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, infoWarning)) = callsite.callee - - val traitMethodArgumentTypes = asm.Type.getArgumentTypes(callee.desc) - - val implClassInternalName = calleeDeclarationClass.internalName + "$class" - - val selfParamTypeV: Either[OptimizerWarning, ClassBType] = calleeDeclarationClass.info.map(_.inlineInfo.traitImplClassSelfType match { - case Some(internalName) => classBTypeFromParsedClassfile(internalName) - case None => calleeDeclarationClass - }) - - def implClassMethodV(implMethodDescriptor: String): Either[OptimizerWarning, MethodNode] = { - byteCodeRepository.methodNode(implClassInternalName, callee.name, implMethodDescriptor).map(_._1) - } - - // The rewrite reading the implementation class and the implementation method from the bytecode - // repository. If either of the two fails, the rewrite is not performed. - val res = for { - selfParamType <- selfParamTypeV - implMethodDescriptor = asm.Type.getMethodDescriptor(asm.Type.getReturnType(callee.desc), selfParamType.toASMType +: traitMethodArgumentTypes: _*) - implClassMethod <- implClassMethodV(implMethodDescriptor) - implClassBType = classBTypeFromParsedClassfile(implClassInternalName) - selfTypeOk <- calleeDeclarationClass.isSubtypeOf(selfParamType) - } yield { - - // The self parameter type may be incompatible with the trait type. - // trait T { self: S => def foo = 1 } - // The $self parameter type of T$class.foo is S, which may be unrelated to T. If we re-write - // a call to T.foo to T$class.foo, we need to cast the receiver to S, otherwise we get a - // VerifyError. We run a `SourceInterpreter` to find all producer instructions of the - // receiver value and add a cast to the self type after each. - if (!selfTypeOk) { - // We don't need to worry about the method being too large for running an analysis. - // Callsites of large methods are not added to the call graph. - val analyzer = new AsmAnalyzer(callsite.callsiteMethod, callsite.callsiteClass.internalName, new Analyzer(new SourceInterpreter)) - val receiverValue = analyzer.frameAt(callsite.callsiteInstruction).peekStack(traitMethodArgumentTypes.length) - for (i <- receiverValue.insns.asScala) { - val cast = new TypeInsnNode(CHECKCAST, selfParamType.internalName) - callsite.callsiteMethod.instructions.insert(i, cast) - } - } - - val newCallsiteInstruction = new MethodInsnNode(INVOKESTATIC, implClassInternalName, callee.name, implMethodDescriptor, false) - callsite.callsiteMethod.instructions.insert(callsite.callsiteInstruction, newCallsiteInstruction) - callsite.callsiteMethod.instructions.remove(callsite.callsiteInstruction) - - callGraph.removeCallsite(callsite.callsiteInstruction, callsite.callsiteMethod) - val staticCallSamParamTypes = { - if (selfParamType.info.get.inlineInfo.sam.isEmpty) samParamTypes - 0 - else samParamTypes.updated(0, selfParamType) - } - val staticCallsite = callsite.copy( - callsiteInstruction = newCallsiteInstruction, - callee = Right(Callee( - callee = implClassMethod, - calleeDeclarationClass = implClassBType, - safeToInline = true, - safeToRewrite = false, - canInlineFromSource = canInlineFromSource, - annotatedInline = annotatedInline, - annotatedNoInline = annotatedNoInline, - samParamTypes = staticCallSamParamTypes, - calleeInfoWarning = infoWarning)) - ) - callGraph.addCallsite(staticCallsite) - } - - for (warning <- res.left) { - val Right(callee) = callsite.callee - val newCallee = callee.copy(calleeInfoWarning = Some(RewriteTraitCallToStaticImplMethodFailed(calleeDeclarationClass.internalName, callee.callee.name, callee.callee.desc, warning))) - callGraph.addCallsite(callsite.copy(callee = Right(newCallee))) - } - } - /** * Returns the callsites that can be inlined. Ensures that the returned inline request graph does * not contain cycles. diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala index 7e35d0e7f0..35735794b1 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala @@ -41,7 +41,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) { compilingMethods.map(methodNode => { var requests = Set.empty[InlineRequest] callGraph.callsites(methodNode).valuesIterator foreach { - case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, canInlineFromSource, calleeAnnotatedInline, _, _, callsiteWarning)), _, _, _, pos, _, _) => + case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, canInlineFromSource, calleeAnnotatedInline, _, _, callsiteWarning)), _, _, _, pos, _, _) => inlineRequest(callsite) match { case Some(Right(req)) => requests += req case Some(Left(w)) => @@ -57,9 +57,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) { // reason is, for example, mixed compilation (which has a separate -Yopt-warning flag). def initMsg = s"${BackendReporting.methodSignature(calleeDeclClass.internalName, callee)} is annotated @inline but cannot be inlined" def warnMsg = callsiteWarning.map(" Possible reason:\n" + _).getOrElse("") - if (doRewriteTraitCallsite(callsite)) - backendReporting.inlinerWarning(pos, s"$initMsg: the trait method call could not be rewritten to the static implementation method." + warnMsg) - else if (!safeToInline) + if (!safeToInline) backendReporting.inlinerWarning(pos, s"$initMsg: the method is not final and may be overridden." + warnMsg) else backendReporting.inlinerWarning(pos, s"$initMsg." + warnMsg) -- cgit v1.2.3