Skip to content

Commit c524f18

Browse files
committed
Merge pull request scala#4966 from lrytz/inlineProject
SD-79 don't issue spurious inliner warnings under l:project
2 parents c672d68 + 363bad3 commit c524f18

File tree

5 files changed

+29
-15
lines changed

5 files changed

+29
-15
lines changed

src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,13 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
132132
(declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)]
133133
} yield {
134134
val declarationClassBType = classBTypeFromClassNode(declarationClassNode)
135-
val CallsiteInfo(safeToInline, safeToRewrite, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source)
135+
val CallsiteInfo(safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source)
136136
Callee(
137137
callee = method,
138138
calleeDeclarationClass = declarationClassBType,
139139
safeToInline = safeToInline,
140140
safeToRewrite = safeToRewrite,
141+
canInlineFromSource = canInlineFromSource,
141142
annotatedInline = annotatedInline,
142143
annotatedNoInline = annotatedNoInline,
143144
samParamTypes = samParamTypes,
@@ -255,7 +256,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
255256
/**
256257
* Just a named tuple used as return type of `analyzeCallsite`.
257258
*/
258-
private case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean,
259+
private case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean,
259260
annotatedInline: Boolean, annotatedNoInline: Boolean,
260261
samParamTypes: IntMap[ClassBType],
261262
warning: Option[CalleeInfoWarning])
@@ -316,20 +317,21 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
316317
!BytecodeUtils.isConstructor(calleeMethodNode) &&
317318
!BytecodeUtils.isNativeMethod(calleeMethodNode) &&
318319
!BytecodeUtils.hasCallerSensitiveAnnotation(calleeMethodNode),
319-
safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2)
320-
annotatedInline = methodInlineInfo.annotatedInline,
321-
annotatedNoInline = methodInlineInfo.annotatedNoInline,
322-
samParamTypes = samParamTypes(calleeMethodNode, receiverType),
323-
warning = warning)
320+
safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2)
321+
canInlineFromSource = canInlineFromSource,
322+
annotatedInline = methodInlineInfo.annotatedInline,
323+
annotatedNoInline = methodInlineInfo.annotatedNoInline,
324+
samParamTypes = samParamTypes(calleeMethodNode, receiverType),
325+
warning = warning)
324326

325327
case None =>
326328
val warning = MethodInlineInfoMissing(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, calleeDeclarationClassBType.info.orThrow.inlineInfo.warning)
327-
CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning))
329+
CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning))
328330
}
329331
} catch {
330332
case Invalid(noInfo: NoClassBTypeInfo) =>
331333
val warning = MethodInlineInfoError(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, noInfo)
332-
CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning))
334+
CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning))
333335
}
334336
}
335337

@@ -393,7 +395,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
393395
* gathering the information about this callee.
394396
*/
395397
final case class Callee(callee: MethodNode, calleeDeclarationClass: ClassBType,
396-
safeToInline: Boolean, safeToRewrite: Boolean,
398+
safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean,
397399
annotatedInline: Boolean, annotatedNoInline: Boolean,
398400
samParamTypes: IntMap[ClassBType],
399401
calleeInfoWarning: Option[CalleeInfoWarning]) {

src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,13 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
358358
val callee = bodyMethod.map({
359359
case (bodyMethodNode, bodyMethodDeclClass) =>
360360
val bodyDeclClassType = classBTypeFromParsedClassfile(bodyMethodDeclClass)
361+
val canInlineFromSource = compilerSettings.YoptInlineGlobal || bodyMethodIsBeingCompiled
361362
Callee(
362363
callee = bodyMethodNode,
363364
calleeDeclarationClass = bodyDeclClassType,
364-
safeToInline = compilerSettings.YoptInlineGlobal || bodyMethodIsBeingCompiled,
365+
safeToInline = canInlineFromSource,
365366
safeToRewrite = false, // the lambda body method is not a trait interface method
367+
canInlineFromSource = canInlineFromSource,
366368
annotatedInline = false,
367369
annotatedNoInline = false,
368370
samParamTypes = callGraph.samParamTypes(bodyMethodNode, bodyDeclClassType),

src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
8383
* True for statically resolved trait callsites that should be rewritten to the static implementation method.
8484
*/
8585
def doRewriteTraitCallsite(callsite: Callsite) = callsite.callee match {
86-
case Right(Callee(_, _, _, safeToRewrite, _, _, _, _)) => safeToRewrite
86+
case Right(callee) => callee.safeToRewrite
8787
case _ => false
8888
}
8989

@@ -101,7 +101,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
101101
// If the callsite was eliminated by DCE, do nothing.
102102
if (!callGraph.containsCallsite(callsite)) return
103103

104-
val Right(Callee(callee, calleeDeclarationClass, _, _, annotatedInline, annotatedNoInline, samParamTypes, infoWarning)) = callsite.callee
104+
val Right(Callee(callee, calleeDeclarationClass, _, _, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, infoWarning)) = callsite.callee
105105

106106
val traitMethodArgumentTypes = asm.Type.getArgumentTypes(callee.desc)
107107

@@ -159,6 +159,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
159159
calleeDeclarationClass = implClassBType,
160160
safeToInline = true,
161161
safeToRewrite = false,
162+
canInlineFromSource = canInlineFromSource,
162163
annotatedInline = annotatedInline,
163164
annotatedNoInline = annotatedNoInline,
164165
samParamTypes = staticCallSamParamTypes,

src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
4141
compilingMethods.map(methodNode => {
4242
var requests = Set.empty[InlineRequest]
4343
callGraph.callsites(methodNode).valuesIterator foreach {
44-
case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, calleeAnnotatedInline, _, _, callsiteWarning)), _, _, _, pos, _, _) =>
44+
case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, canInlineFromSource, calleeAnnotatedInline, _, _, callsiteWarning)), _, _, _, pos, _, _) =>
4545
inlineRequest(callsite) match {
4646
case Some(Right(req)) => requests += req
4747
case Some(Left(w)) =>
@@ -52,7 +52,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
5252
}
5353

5454
case None =>
55-
if (calleeAnnotatedInline && !callsite.annotatedNoInline && bTypes.compilerSettings.YoptWarningEmitAtInlineFailed) {
55+
if (canInlineFromSource && calleeAnnotatedInline && !callsite.annotatedNoInline && bTypes.compilerSettings.YoptWarningEmitAtInlineFailed) {
5656
// if the callsite is annotated @inline, we report an inline warning even if the underlying
5757
// reason is, for example, mixed compilation (which has a separate -Yopt-warning flag).
5858
def initMsg = s"${BackendReporting.methodSignature(calleeDeclClass.internalName, callee)} is annotated @inline but cannot be inlined"

test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,4 +1515,13 @@ class InlinerTest extends ClearAfterClass {
15151515
"C$$$anonfun$2", IRETURN,
15161516
-1 /*A*/, "C$$$anonfun$3", IRETURN))
15171517
}
1518+
1519+
@Test
1520+
def inlineProject(): Unit = {
1521+
val codeA = "final class A { @inline def f = 1 }"
1522+
val codeB = "class B { def t(a: A) = a.f }"
1523+
// tests that no warning is emitted
1524+
val List(a, b) = compileClassesSeparately(List(codeA, codeB), extraArgs = "-Yopt:l:project -Yopt-warnings")
1525+
assertInvoke(getSingleMethod(b, "t"), "A", "f")
1526+
}
15181527
}

0 commit comments

Comments
 (0)