diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2012-11-16 16:25:49 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2012-11-16 16:25:49 -0800 |
commit | 3acd3eb3ed957727757c9171b39f9f5bcdf34917 (patch) | |
tree | 9cd34da810f29f858d46eb3f0f2a82a689948aeb /src/compiler | |
parent | 52ec695a98608128be2429d813fc5a045a092988 (diff) | |
parent | 768a4082a6090835afef34ee38c2c398da335b01 (diff) | |
download | scala-3acd3eb3ed957727757c9171b39f9f5bcdf34917.tar.gz scala-3acd3eb3ed957727757c9171b39f9f5bcdf34917.tar.bz2 scala-3acd3eb3ed957727757c9171b39f9f5bcdf34917.zip |
Merge pull request #1635 from paulp/slick-regression-2
Fix for overly eager package object initialization.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 78380ad054..a8d7de6362 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -761,25 +761,44 @@ trait Contexts { self: Analyzer => * info of the package object. However to avoid cycles we'll check * what other ways we can before pushing that way. */ - def isInPackageObject(sym: Symbol, pkg: Symbol) = { - val pkgClass = if (pkg.isTerm) pkg.moduleClass else pkg + def isInPackageObject(sym: Symbol, pkg: Symbol): Boolean = { + def uninitialized(what: String) = { + log(s"Cannot look for $sym in package object of $pkg; $what is not initialized.") + false + } + def pkgClass = if (pkg.isTerm) pkg.moduleClass else pkg def matchesInfo = ( - pkg.isInitialized && { - // need to be careful here to not get a cyclic reference during bootstrap + // need to be careful here to not get a cyclic reference during bootstrap + if (pkg.isInitialized) { val module = pkg.info member nme.PACKAGEkw - module.isInitialized && (module.info.member(sym.name).alternatives contains sym) + if (module.isInitialized) + module.info.member(sym.name).alternatives contains sym + else + uninitialized("" + module) } + else uninitialized("" + pkg) ) def inPackageObject(sym: Symbol) = ( - !sym.isPackage - && !sym.owner.isPackageClass - && (sym.owner ne NoSymbol) - && (sym.owner.owner == pkgClass || matchesInfo) + // To be in the package object, one of these must be true: + // 1) sym.owner is a package object class, and sym.owner.owner is the package class for `pkg` + // 2) sym.owner is inherited by the correct package object class + // We try to establish 1) by inspecting the owners directly, and then we try + // to rule out 2), and only if both those fail do we resort to looking in the info. + !sym.isPackage && (sym.owner ne NoSymbol) && ( + if (sym.owner.isPackageObjectClass) + sym.owner.owner == pkgClass + else + !sym.owner.isPackageClass && matchesInfo + ) ) + // An overloaded symbol might not have the expected owner! + // The alternatives must be inspected directly. pkgClass.isPackageClass && ( - if (sym.isOverloaded) sym.alternatives forall inPackageObject - else inPackageObject(sym) + if (sym.isOverloaded) + sym.alternatives forall (isInPackageObject(_, pkg)) + else + inPackageObject(sym) ) } |