summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2016-06-06 11:51:56 -0700
committerAdriaan Moors <adriaan@lightbend.com>2016-06-06 11:51:56 -0700
commit79e7334f93da4717ee846f74e48ab53533e6756d (patch)
tree384f2680be482981370c64c7112aaed14b92cc0f /src
parent28e0e18106a93fd8fd9a086c29836631c754ba35 (diff)
parenta1ea0aa0a6136c13baa41268d7dbd4197924d3c9 (diff)
downloadscala-79e7334f93da4717ee846f74e48ab53533e6756d.tar.gz
scala-79e7334f93da4717ee846f74e48ab53533e6756d.tar.bz2
scala-79e7334f93da4717ee846f74e48ab53533e6756d.zip
Merge pull request #5202 from lrytz/lineNumbers
Keep line numbers when inlining from the same compilation unit
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala25
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala67
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala25
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala13
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
11 files changed, 84 insertions, 89 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
index 02dc2b8ede..584b11d4ed 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
@@ -77,15 +77,16 @@ abstract class GenBCode extends BCodeSyncAndTry {
/* ---------------- q2 ---------------- */
- case class Item2(arrivalPos: Int,
- mirror: asm.tree.ClassNode,
- plain: asm.tree.ClassNode,
- bean: asm.tree.ClassNode,
- outFolder: scala.tools.nsc.io.AbstractFile) {
+ case class Item2(arrivalPos: Int,
+ mirror: asm.tree.ClassNode,
+ plain: asm.tree.ClassNode,
+ bean: asm.tree.ClassNode,
+ sourceFilePath: String,
+ outFolder: scala.tools.nsc.io.AbstractFile) {
def isPoison = { arrivalPos == Int.MaxValue }
}
- private val poison2 = Item2(Int.MaxValue, null, null, null, null)
+ private val poison2 = Item2(Int.MaxValue, null, null, null, null, null)
private val q2 = new _root_.java.util.LinkedList[Item2]
/* ---------------- q3 ---------------- */
@@ -205,6 +206,7 @@ abstract class GenBCode extends BCodeSyncAndTry {
val item2 =
Item2(arrivalPos,
mirrorC, plainC, beanC,
+ cunit.source.file.canonicalPath,
outF)
q2 add item2 // at the very end of this method so that no Worker2 thread starts mutating before we're done.
@@ -226,10 +228,11 @@ abstract class GenBCode extends BCodeSyncAndTry {
// add classes to the bytecode repo before building the call graph: the latter needs to
// look up classes and methods in the code repo.
if (settings.optAddToBytecodeRepository) q2.asScala foreach {
- case Item2(_, mirror, plain, bean, _) =>
- if (mirror != null) byteCodeRepository.add(mirror, ByteCodeRepository.CompilationUnit)
- if (plain != null) byteCodeRepository.add(plain, ByteCodeRepository.CompilationUnit)
- if (bean != null) byteCodeRepository.add(bean, ByteCodeRepository.CompilationUnit)
+ case Item2(_, mirror, plain, bean, sourceFilePath, _) =>
+ val someSourceFilePath = Some(sourceFilePath)
+ if (mirror != null) byteCodeRepository.add(mirror, someSourceFilePath)
+ if (plain != null) byteCodeRepository.add(plain, someSourceFilePath)
+ if (bean != null) byteCodeRepository.add(bean, someSourceFilePath)
}
if (settings.optBuildCallGraph) q2.asScala foreach { item =>
// skip call graph for mirror / bean: wd don't inline into tem, and they are not used in the plain class
@@ -286,7 +289,7 @@ abstract class GenBCode extends BCodeSyncAndTry {
cw.toByteArray
}
- val Item2(arrivalPos, mirror, plain, bean, outFolder) = item
+ val Item2(arrivalPos, mirror, plain, bean, _, outFolder) = item
val mirrorC = if (mirror == null) null else SubItem3(mirror.name, getByteArray(mirror))
val plainC = SubItem3(plain.name, getByteArray(plain))
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
index 6d3c3f3863..9abd1d8006 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
@@ -98,7 +98,7 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
* a boolean indicating if the instruction list contains an instantiation of a serializable SAM
* type.
*/
- def cloneInstructions(methodNode: MethodNode, labelMap: Map[LabelNode, LabelNode]): (InsnList, Map[AbstractInsnNode, AbstractInsnNode], Boolean) = {
+ def cloneInstructions(methodNode: MethodNode, labelMap: Map[LabelNode, LabelNode], keepLineNumbers: Boolean): (InsnList, Map[AbstractInsnNode, AbstractInsnNode], Boolean) = {
val javaLabelMap = labelMap.asJava
val result = new InsnList
var map = Map.empty[AbstractInsnNode, AbstractInsnNode]
@@ -112,9 +112,11 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
}
case _ =>
}
- val cloned = ins.clone(javaLabelMap)
- result add cloned
- map += ((ins, cloned))
+ if (keepLineNumbers || !ins.isInstanceOf[LineNumberNode]) {
+ val cloned = ins.clone(javaLabelMap)
+ result add cloned
+ map += ((ins, cloned))
+ }
}
(result, map, hasSerializableClosureInstantiation)
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala
index 16590ec75c..78acd72dba 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala
@@ -15,7 +15,6 @@ import scala.tools.asm.Attribute
import scala.tools.nsc.backend.jvm.BackendReporting._
import scala.tools.nsc.util.ClassPath
import BytecodeUtils._
-import ByteCodeRepository._
import BTypes.InternalName
import java.util.concurrent.atomic.AtomicLong
@@ -29,9 +28,10 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT)
import btypes._
/**
- * ClassNodes for classes being compiled in the current compilation run.
+ * Contains ClassNodes and the canonical path of the source file path of classes being compiled in
+ * the current compilation run.
*/
- val compilingClasses: concurrent.Map[InternalName, ClassNode] = recordPerRunCache(concurrent.TrieMap.empty)
+ val compilingClasses: concurrent.Map[InternalName, (ClassNode, String)] = recordPerRunCache(concurrent.TrieMap.empty)
/**
* Cache for parsed ClassNodes.
@@ -67,20 +67,35 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT)
}
}
- def add(classNode: ClassNode, source: Source) = {
- if (source == CompilationUnit) compilingClasses(classNode.name) = classNode
- else parsedClasses(classNode.name) = Right((classNode, lruCounter.incrementAndGet()))
+ def add(classNode: ClassNode, sourceFilePath: Option[String]) = sourceFilePath match {
+ case Some(path) if path != "<no file>" => compilingClasses(classNode.name) = (classNode, path)
+ case _ => parsedClasses(classNode.name) = Right((classNode, lruCounter.incrementAndGet()))
+ }
+
+ private def parsedClassNode(internalName: InternalName): Either[ClassNotFound, ClassNode] = {
+ val r = parsedClasses.get(internalName) match {
+ case Some(l @ Left(_)) => l
+ case Some(r @ Right((classNode, _))) =>
+ parsedClasses(internalName) = Right((classNode, lruCounter.incrementAndGet()))
+ r
+ case None =>
+ limitCacheSize()
+ val res = parseClass(internalName).map((_, lruCounter.incrementAndGet()))
+ parsedClasses(internalName) = res
+ res
+ }
+ r.map(_._1)
}
/**
- * The class node and source for an internal name. If the class node is not yet available, it is
- * parsed from the classfile on the compile classpath.
+ * The class node and source file path (if the class is being compiled) for an internal name. If
+ * the class node is not yet available, it is parsed from the classfile on the compile classpath.
*/
- def classNodeAndSource(internalName: InternalName): Either[ClassNotFound, (ClassNode, Source)] = {
- classNode(internalName) map (n => {
- val source = if (compilingClasses contains internalName) CompilationUnit else Classfile
- (n, source)
- })
+ def classNodeAndSourceFilePath(internalName: InternalName): Either[ClassNotFound, (ClassNode, Option[String])] = {
+ compilingClasses.get(internalName) match {
+ case Some((c, p)) => Right((c, Some(p)))
+ case _ => parsedClassNode(internalName).map((_, None))
+ }
}
/**
@@ -88,19 +103,9 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT)
* the classfile on the compile classpath.
*/
def classNode(internalName: InternalName): Either[ClassNotFound, ClassNode] = {
- compilingClasses.get(internalName).map(Right(_)) getOrElse {
- val r = parsedClasses.get(internalName) match {
- case Some(l @ Left(_)) => l
- case Some(r @ Right((classNode, _))) =>
- parsedClasses(internalName) = Right((classNode, lruCounter.incrementAndGet()))
- r
- case None =>
- limitCacheSize()
- val res = parseClass(internalName).map((_, lruCounter.incrementAndGet()))
- parsedClasses(internalName) = res
- res
- }
- r.map(_._1)
+ compilingClasses.get(internalName) match {
+ case Some((c, _)) => Right(c)
+ case None => parsedClassNode(internalName)
}
}
@@ -289,13 +294,3 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT)
}
}
}
-
-object ByteCodeRepository {
- /**
- * The source of a ClassNode in the ByteCodeRepository. Can be either [[CompilationUnit]] if the
- * class is being compiled or [[Classfile]] if the class was parsed from the compilation classpath.
- */
- sealed trait Source
- object CompilationUnit extends Source
- object Classfile extends Source
-}
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 d4ff6493a3..40344809bf 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
@@ -16,7 +16,6 @@ import scala.collection.JavaConverters._
import scala.tools.nsc.backend.jvm.BTypes.InternalName
import scala.tools.nsc.backend.jvm.BackendReporting._
import scala.tools.nsc.backend.jvm.analysis._
-import ByteCodeRepository.{Source, CompilationUnit}
import BytecodeUtils._
class CallGraph[BT <: BTypes](val btypes: BT) {
@@ -128,17 +127,17 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
methodNode.instructions.iterator.asScala foreach {
case call: MethodInsnNode if a.frameAt(call) != null => // skips over unreachable code
val callee: Either[OptimizerWarning, Callee] = for {
- (method, declarationClass) <- byteCodeRepository.methodNode(call.owner, call.name, call.desc): Either[OptimizerWarning, (MethodNode, InternalName)]
- (declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)]
+ (method, declarationClass) <- byteCodeRepository.methodNode(call.owner, call.name, call.desc): Either[OptimizerWarning, (MethodNode, InternalName)]
+ (declarationClassNode, calleeSourceFilePath) <- byteCodeRepository.classNodeAndSourceFilePath(declarationClass): Either[OptimizerWarning, (ClassNode, Option[String])]
} yield {
val declarationClassBType = classBTypeFromClassNode(declarationClassNode)
- val info = analyzeCallsite(method, declarationClassBType, call, source)
+ val info = analyzeCallsite(method, declarationClassBType, call, calleeSourceFilePath)
import info._
Callee(
callee = method,
calleeDeclarationClass = declarationClassBType,
safeToInline = safeToInline,
- canInlineFromSource = canInlineFromSource,
+ sourceFilePath = sourceFilePath,
annotatedInline = annotatedInline,
annotatedNoInline = annotatedNoInline,
samParamTypes = info.samParamTypes,
@@ -256,7 +255,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
/**
* Just a named tuple used as return type of `analyzeCallsite`.
*/
- private case class CallsiteInfo(safeToInline: Boolean, canInlineFromSource: Boolean,
+ private case class CallsiteInfo(safeToInline: Boolean, sourceFilePath: Option[String],
annotatedInline: Boolean, annotatedNoInline: Boolean,
samParamTypes: IntMap[ClassBType],
warning: Option[CalleeInfoWarning])
@@ -264,7 +263,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
/**
* Analyze a callsite and gather meta-data that can be used for inlining decisions.
*/
- private def analyzeCallsite(calleeMethodNode: MethodNode, calleeDeclarationClassBType: ClassBType, call: MethodInsnNode, calleeSource: Source): CallsiteInfo = {
+ private def analyzeCallsite(calleeMethodNode: MethodNode, calleeDeclarationClassBType: ClassBType, call: MethodInsnNode, calleeSourceFilePath: Option[String]): CallsiteInfo = {
val methodSignature = calleeMethodNode.name + calleeMethodNode.desc
try {
@@ -273,8 +272,6 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
// callee, we only check there for the methodInlineInfo, we should find it there.
calleeDeclarationClassBType.info.orThrow.inlineInfo.methodInfos.get(methodSignature) match {
case Some(methodInlineInfo) =>
- val canInlineFromSource = compilerSettings.optInlineGlobal || calleeSource == CompilationUnit
-
val isAbstract = BytecodeUtils.isAbstractMethod(calleeMethodNode)
val receiverType = classBTypeFromParsedClassfile(call.owner)
@@ -308,13 +305,13 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
// static impl method first (safeToRewrite).
CallsiteInfo(
safeToInline =
- canInlineFromSource &&
+ inlinerHeuristics.canInlineFromSource(calleeSourceFilePath) &&
isStaticallyResolved && // (1)
!isAbstract &&
!BytecodeUtils.isConstructor(calleeMethodNode) &&
!BytecodeUtils.isNativeMethod(calleeMethodNode) &&
!BytecodeUtils.hasCallerSensitiveAnnotation(calleeMethodNode),
- canInlineFromSource = canInlineFromSource,
+ sourceFilePath = calleeSourceFilePath,
annotatedInline = methodInlineInfo.annotatedInline,
annotatedNoInline = methodInlineInfo.annotatedNoInline,
samParamTypes = samParamTypes(calleeMethodNode, receiverType),
@@ -322,12 +319,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, IntMap.empty, Some(warning))
+ CallsiteInfo(false, None, 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, IntMap.empty, Some(warning))
+ CallsiteInfo(false, None, false, false, IntMap.empty, Some(warning))
}
}
@@ -389,7 +386,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
* gathering the information about this callee.
*/
final case class Callee(callee: MethodNode, calleeDeclarationClass: btypes.ClassBType,
- safeToInline: Boolean, canInlineFromSource: Boolean,
+ safeToInline: Boolean, sourceFilePath: Option[String],
annotatedInline: Boolean, annotatedNoInline: Boolean,
samParamTypes: IntMap[btypes.ClassBType],
calleeInfoWarning: Option[CalleeInfoWarning]) {
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 7f9858286e..081830d61d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala
@@ -17,7 +17,6 @@ import scala.tools.nsc.backend.jvm.BTypes.InternalName
import BytecodeUtils._
import BackendReporting._
import Opcodes._
-import scala.tools.nsc.backend.jvm.opt.ByteCodeRepository.CompilationUnit
import scala.collection.JavaConverters._
class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
@@ -354,16 +353,15 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
// the method node is needed for building the call graph entry
val bodyMethod = byteCodeRepository.methodNode(lambdaBodyHandle.getOwner, lambdaBodyHandle.getName, lambdaBodyHandle.getDesc)
- def bodyMethodIsBeingCompiled = byteCodeRepository.classNodeAndSource(lambdaBodyHandle.getOwner).map(_._2 == CompilationUnit).getOrElse(false)
+ val sourceFilePath = byteCodeRepository.compilingClasses.get(lambdaBodyHandle.getOwner).map(_._2)
val callee = bodyMethod.map({
case (bodyMethodNode, bodyMethodDeclClass) =>
val bodyDeclClassType = classBTypeFromParsedClassfile(bodyMethodDeclClass)
- val canInlineFromSource = compilerSettings.optInlineGlobal || bodyMethodIsBeingCompiled
Callee(
callee = bodyMethodNode,
calleeDeclarationClass = bodyDeclClassType,
- safeToInline = canInlineFromSource,
- canInlineFromSource = canInlineFromSource,
+ safeToInline = inlinerHeuristics.canInlineFromSource(sourceFilePath),
+ sourceFilePath = sourceFilePath,
annotatedInline = false,
annotatedNoInline = false,
samParamTypes = callGraph.samParamTypes(bodyMethodNode, bodyDeclClassType),
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 809b9e310d..7b4cfe2a18 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -253,7 +253,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
def inlineCallsite(callsite: Callsite): Unit = {
import callsite.{callsiteClass, callsiteMethod, callsiteInstruction, receiverKnownNotNull, callsiteStackHeight}
val Right(callsiteCallee) = callsite.callee
- import callsiteCallee.{callee, calleeDeclarationClass}
+ import callsiteCallee.{callee, calleeDeclarationClass, sourceFilePath}
// Inlining requires the callee not to have unreachable code, the analyzer used below should not
// return any `null` frames. Note that inlining a method can create unreachable code. Example:
@@ -268,11 +268,14 @@ class Inliner[BT <: BTypes](val btypes: BT) {
// New labels for the cloned instructions
val labelsMap = cloneLabels(callee)
- val (clonedInstructions, instructionMap, hasSerializableClosureInstantiation) = cloneInstructions(callee, labelsMap)
- val keepLineNumbers = callsiteClass == calleeDeclarationClass
- if (!keepLineNumbers) {
- removeLineNumberNodes(clonedInstructions)
+ val sameSourceFile = sourceFilePath match {
+ case Some(calleeSource) => byteCodeRepository.compilingClasses.get(callsiteClass.internalName) match {
+ case Some((_, `calleeSource`)) => true
+ case _ => false
+ }
+ case _ => false
}
+ val (clonedInstructions, instructionMap, hasSerializableClosureInstantiation) = cloneInstructions(callee, labelsMap, keepLineNumbers = sameSourceFile)
// local vars in the callee are shifted by the number of locals at the callsite
val localVarShift = callsiteMethod.maxLocals
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 17807fb385..009742501e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
@@ -22,6 +22,8 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
for (pr <- post) assert(pr.callsite.callsiteMethod == callsite.callee.get.callee, s"Callsite method mismatch: main $callsite - post ${pr.callsite}")
}
+ def canInlineFromSource(sourceFilePath: Option[String]) = compilerSettings.optInlineGlobal || sourceFilePath.isDefined
+
/**
* Select callsites from the call graph that should be inlined, grouped by the containing method.
* Cyclic inlining requests are allowed, the inliner will eliminate requests to break cycles.
@@ -32,14 +34,14 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
// classpath. In order to get only the callsites being compiled, we start at the map of
// compilingClasses in the byteCodeRepository.
val compilingMethods = for {
- classNode <- byteCodeRepository.compilingClasses.valuesIterator
- methodNode <- classNode.methods.iterator.asScala
+ (classNode, _) <- byteCodeRepository.compilingClasses.valuesIterator
+ methodNode <- classNode.methods.iterator.asScala
} yield methodNode
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, sourceFilePath, calleeAnnotatedInline, _, _, callsiteWarning)), _, _, _, pos, _, _) =>
inlineRequest(callsite, requests) match {
case Some(Right(req)) => requests += req
case Some(Left(w)) =>
@@ -50,7 +52,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
}
case None =>
- if (canInlineFromSource && calleeAnnotatedInline && !callsite.annotatedNoInline && bTypes.compilerSettings.optWarningEmitAtInlineFailed) {
+ if (canInlineFromSource(sourceFilePath) && calleeAnnotatedInline && !callsite.annotatedNoInline && bTypes.compilerSettings.optWarningEmitAtInlineFailed) {
// if the callsite is annotated @inline, we report an inline warning even if the underlying
// reason is, for example, mixed compilation (which has a separate -opt-warning flag).
def initMsg = s"${BackendReporting.methodSignature(calleeDeclClass.internalName, callee)} is annotated @inline but cannot be inlined"
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 2773ee19cf..9c1ba7ced1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -431,6 +431,7 @@ trait Namers extends MethodSynthesis {
&& !(module isCoDefinedWith clazz)
&& module.exists
&& clazz.exists
+ && (currentRun.compiles(clazz) == currentRun.compiles(module))
)
if (fails) {
reporter.error(tree.pos, (
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index 230d30c74e..e06decea6d 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -234,14 +234,8 @@ class Flags extends ModifierFlags {
*/
final val AllFlags = -1L
- /** These flags can be set when class or module symbol is first created.
- * They are the only flags to survive a call to resetFlags().
- */
- final val TopLevelCreationFlags =
- MODULE | PACKAGE | FINAL | JAVA
-
// TODO - there's no call to slap four flags onto every package.
- final val PackageFlags = TopLevelCreationFlags
+ final val PackageFlags = MODULE | PACKAGE | FINAL | JAVA
// FINAL not included here due to possibility of object overriding.
// In fact, FINAL should not be attached regardless. We should be able
@@ -301,7 +295,7 @@ class Flags extends ModifierFlags {
final val ConstrFlags = JAVA
/** Module flags inherited by their module-class */
- final val ModuleToClassFlags = AccessFlags | TopLevelCreationFlags | CASE | SYNTHETIC
+ final val ModuleToClassFlags = AccessFlags | PackageFlags | CASE | SYNTHETIC
/** These flags are not pickled */
final val FlagsNotPickled = IS_ERROR | OVERLOADED | LIFTED | TRANS_FLAG | LOCKED | TRIEDCOOKING
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 756300d403..3d1c160d52 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -273,7 +273,7 @@ trait Mirrors extends api.Mirrors {
// is very beneficial for a handful of bootstrap symbols to have
// first class identities
sealed trait WellKnownSymbol extends Symbol {
- this initFlags (TopLevelCreationFlags | STATIC)
+ this initFlags (PackageFlags | STATIC)
}
// Features common to RootClass and RootPackage, the roots of all
// type and term symbols respectively.
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 6f2d8d802a..ab52a875f8 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -725,7 +725,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def setFlag(mask: Long): this.type = { _rawflags |= mask ; this }
def resetFlag(mask: Long): this.type = { _rawflags &= ~mask ; this }
- def resetFlags() { rawflags &= TopLevelCreationFlags }
+ def resetFlags() { rawflags = 0 }
/** Default implementation calls the generic string function, which
* will print overloaded flags as <flag1/flag2/flag3>. Subclasses