diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-07-25 17:47:56 +0200 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-07-25 17:47:56 +0200 |
commit | e89fe92ac34b111ba887a79ac788552135c7cce0 (patch) | |
tree | 6928d27ce37c81a925a05b6862730d7125357fe3 /src/compiler/scala/tools/nsc/symtab | |
parent | 33b847b7f56cbc5add74692385a9e0f5ad41c7a6 (diff) | |
parent | a8c88b194eefd5d4d55361b934faa0ebd954ef08 (diff) | |
download | scala-e89fe92ac34b111ba887a79ac788552135c7cce0.tar.gz scala-e89fe92ac34b111ba887a79ac788552135c7cce0.tar.bz2 scala-e89fe92ac34b111ba887a79ac788552135c7cce0.zip |
Merge pull request #3826 from lrytz/opt/refactorTracked
Assortiment of cleanups and comments around the backend
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 447fa66ae4..82c2a4d6ed 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -240,6 +240,12 @@ abstract class SymbolLoaders { } } + private def phaseBeforeRefchecks: Phase = { + var resPhase = phase + while (resPhase.refChecked) resPhase = resPhase.prev + resPhase + } + /** * Load contents of a package */ @@ -248,19 +254,24 @@ abstract class SymbolLoaders { protected def doComplete(root: Symbol) { assert(root.isPackageClass, root) - root.setInfo(new PackageClassInfoType(newScope, root)) - - if (!root.isRoot) { - for (classRep <- classpath.classes) { - initializeFromClassPath(root, classRep) - } - } - if (!root.isEmptyPackageClass) { - for (pkg <- classpath.packages) { - enterPackage(root, pkg.name, new PackageLoader(pkg)) + // Time travel to a phase before refchecks avoids an initialization issue. `openPackageModule` + // creates a module symbol and invokes invokes `companionModule` while the `infos` field is + // still null. This calls `isModuleNotMethod`, which forces the `info` if run after refchecks. + enteringPhase(phaseBeforeRefchecks) { + root.setInfo(new PackageClassInfoType(newScope, root)) + + if (!root.isRoot) { + for (classRep <- classpath.classes) { + initializeFromClassPath(root, classRep) + } } + if (!root.isEmptyPackageClass) { + for (pkg <- classpath.packages) { + enterPackage(root, pkg.name, new PackageLoader(pkg)) + } - openPackageModule(root) + openPackageModule(root) + } } } } @@ -290,7 +301,13 @@ abstract class SymbolLoaders { protected def doComplete(root: Symbol) { val start = if (Statistics.canEnable) Statistics.startTimer(classReadNanos) else null - classfileParser.parse(classfile, root) + + // Running the classfile parser after refchecks can lead to "illegal class file dependency" + // errors. More concretely, the classfile parser calls "sym.companionModule", which calls + // "isModuleNotMethod" on the companion. After refchecks, this method forces the info, which + // may run the classfile parser. This produces the error. + enteringPhase(phaseBeforeRefchecks)(classfileParser.parse(classfile, root)) + if (root.associatedFile eq NoAbstractFile) { root match { // In fact, the ModuleSymbol forwards its setter to the module class |