diff options
5 files changed, 38 insertions, 28 deletions
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 98466ebb2b..0dff1adda9 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -242,12 +242,20 @@ abstract class SymbolTable extends macros.Universe finally popPhase(saved) } + def slowButSafeEnteringPhase[T](ph: Phase)(op: => T): T = { + if (isCompilerUniverse) enteringPhase(ph)(op) + else op + } + @inline final def exitingPhase[T](ph: Phase)(op: => T): T = enteringPhase(ph.next)(op) @inline final def enteringPrevPhase[T](op: => T): T = enteringPhase(phase.prev)(op) @inline final def enteringPhaseNotLaterThan[T](target: Phase)(op: => T): T = if (isAtPhaseAfter(target)) enteringPhase(target)(op) else op + def slowButSafeEnteringPhaseNotLaterThan[T](target: Phase)(op: => T): T = + if (isCompilerUniverse) enteringPhaseNotLaterThan(target)(op) else op + final def isValid(period: Period): Boolean = period != 0 && runId(period) == currentRunId && { val pid = phaseId(period) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 123e213f50..868913c82f 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1565,6 +1565,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => * assumption: if a type starts out as monomorphic, it will not acquire * type parameters later. */ + // NOTE: overridden in SynchronizedSymbols with the code copy/pasted + // don't forget to modify the code over there if you modify this method def unsafeTypeParams: List[Symbol] = if (isMonomorphicType) Nil else enteringPhase(unsafeTypeParamPhase)(rawInfo.typeParams) @@ -1573,6 +1575,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => * assumption: if a type starts out as monomorphic, it will not acquire * type parameters later. */ + // NOTE: overridden in SynchronizedSymbols with the code copy/pasted + // don't forget to modify the code over there if you modify this method def typeParams: List[Symbol] = if (isMonomorphicType) Nil else { diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index c4f1f0cf96..a6c34935ad 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -659,7 +659,7 @@ abstract class UnPickler { override def complete(sym: Symbol) : Unit = try { val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType` if (p ne null) - enteringPhase(p) (sym setInfo tp) + slowButSafeEnteringPhase(p) (sym setInfo tp) if (currentRunId != definedAtRunId) sym.setInfo(adaptToNewRunMap(tp)) } @@ -677,7 +677,7 @@ abstract class UnPickler { super.complete(sym) var alias = at(j, readSymbol) if (alias.isOverloaded) - alias = enteringPhase(picklerPhase)((alias suchThat (alt => sym.tpe =:= sym.owner.thisType.memberType(alt)))) + alias = slowButSafeEnteringPhase(picklerPhase)((alias suchThat (alt => sym.tpe =:= sym.owner.thisType.memberType(alt)))) sym.asInstanceOf[TermSymbol].setAlias(alias) } diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index 3e01a6df02..3e149c1fe0 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -17,37 +17,13 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => * is found, a package is created instead. */ class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader with FlagAssigningCompleter { -// def makePackage() { -// println("wrong guess; making package "+clazz) -// val ptpe = newPackageType(module.moduleClass) -// for (sym <- List(clazz, module, module.moduleClass)) { -// sym setFlag Flags.PACKAGE -// sym setInfo ptpe -// } -// } - override def complete(sym: Symbol) = { debugInfo("completing "+sym+"/"+clazz.fullName) assert(sym == clazz || sym == module || sym == module.moduleClass) -// try { - enteringPhaseNotLaterThan(picklerPhase) { + slowButSafeEnteringPhaseNotLaterThan(picklerPhase) { val loadingMirror = mirrorThatLoaded(sym) val javaClass = loadingMirror.javaClass(clazz.javaClassName) loadingMirror.unpickleClass(clazz, module, javaClass) -// } catch { -// case ex: ClassNotFoundException => makePackage() -// case ex: NoClassDefFoundError => makePackage() - // Note: We catch NoClassDefFoundError because there are situations - // where a package and a class have the same name except for capitalization. - // It seems in this case the class is loaded even if capitalization differs - // but then a NoClassDefFound error is issued with a ("wrong name: ...") - // reason. (I guess this is a concession to Windows). - // The present behavior is a bit too forgiving, in that it masks - // all class load errors, not just wrong name errors. We should try - // to be more discriminating. To get on the right track simply delete - // the clause above and load a collection class such as collection.Iterable. - // You'll see an error that class `parallel` has the wrong name. -// } } } override def load(sym: Symbol) = complete(sym) diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 615ba6f386..c0b4261d11 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -45,7 +45,29 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb override def updateInfo(info: Type): Symbol = synchronized { super.updateInfo(info) } override def rawInfo: Type = synchronized { super.rawInfo } - override def typeParams: List[Symbol] = synchronized { super.typeParams } + override def typeParams: List[Symbol] = synchronized { + if (isCompilerUniverse) super.typeParams + else { + if (isMonomorphicType) Nil + else { + // analogously to the "info" getter, here we allow for two completions: + // one: sourceCompleter to LazyType, two: LazyType to completed type + if (validTo == NoPeriod) + rawInfo load this + if (validTo == NoPeriod) + rawInfo load this + + rawInfo.typeParams + } + } + } + override def unsafeTypeParams: List[Symbol] = synchronized { + if (isCompilerUniverse) super.unsafeTypeParams + else { + if (isMonomorphicType) Nil + else rawInfo.typeParams + } + } override def reset(completer: Type): this.type = synchronized { super.reset(completer) } |