diff options
author | Paul Phillips <paulp@improving.org> | 2012-10-31 08:26:18 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-10-31 08:49:56 -0700 |
commit | 1e1199d8abbd81ab2fa3b9cbab0290d6793e0945 (patch) | |
tree | bde1e98d0f4a060d14e6ce681366d82f533d0ceb /src/reflect | |
parent | b480d991072e6e68ed46574d87e4483da778ff0e (diff) | |
download | scala-1e1199d8abbd81ab2fa3b9cbab0290d6793e0945.tar.gz scala-1e1199d8abbd81ab2fa3b9cbab0290d6793e0945.tar.bz2 scala-1e1199d8abbd81ab2fa3b9cbab0290d6793e0945.zip |
Fix for -Xcheckinit failures.
The GenASM phase had an eager val which required loading
a bunch of symbols, which meant an earlier call to isPastTyper
could lead to a cycle of the form:
new Run
new GenASM
rootMirror.getRequiredClass
findMember
defineBaseClassesOfCompoundType
isPastTyper
currentRun.typerPhase
and the opening "new Run" hasn't yet caught up to where
currentRun.typerPhase is set.
This was remedied by making the eager val lazy, and
substantially hardened against recurrence via a method on
global "isGlobalInitialized" which verifies that both
the definitions object and the root mirror have completed
their init methods.
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/Mirrors.scala | 5 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 2 |
2 files changed, 6 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 019cf7f908..d16374476a 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -20,6 +20,8 @@ trait Mirrors extends api.Mirrors { trait RootSymbol extends Symbol { def mirror: Mirror } abstract class RootsBase(rootOwner: Symbol) extends scala.reflect.api.Mirror[Mirrors.this.type] { thisMirror => + private[this] var initialized = false + def isMirrorInitialized = initialized protected[scala] def rootLoader: LazyType @@ -229,6 +231,7 @@ trait Mirrors extends api.Mirrors { // } def init() { + if (initialized) return // Still fiddling with whether it's cleaner to do some of this setup here // or from constructors. The latter approach tends to invite init order issues. @@ -240,6 +243,8 @@ trait Mirrors extends api.Mirrors { RootClass.info.decls enter EmptyPackage RootClass.info.decls enter RootPackage + + initialized = true } } diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 92db92d5f3..b6c67ad63e 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1728,7 +1728,7 @@ trait Types extends api.Types { self: SymbolTable => protected def defineBaseClassesOfCompoundType(tpe: CompoundType) { def define = defineBaseClassesOfCompoundType(tpe, force = false) - if (isPastTyper || !breakCycles) define + if (!breakCycles || isPastTyper) define else tpe match { // non-empty parents helpfully excludes all package classes case tpe @ ClassInfoType(_ :: _, _, clazz) if !clazz.isAnonOrRefinementClass => |