From d171b2cc16cc129e0f3aa03c3df9b2fb86208aa6 Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Wed, 10 Aug 2016 09:30:49 +0100 Subject: Partial fix for SI-7046 --- src/reflect/scala/reflect/internal/StdAttachments.scala | 6 ++++++ src/reflect/scala/reflect/internal/Symbols.scala | 17 ++++++++++++++++- src/reflect/scala/reflect/internal/Types.scala | 5 +++++ .../scala/reflect/runtime/JavaUniverseForce.scala | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src/reflect/scala') diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index cca33253be..3df31b538c 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -52,4 +52,10 @@ trait StdAttachments { /** Untyped list of subpatterns attached to selector dummy. */ case class SubpatternsAttachment(patterns: List[Tree]) + + /** Attached to a class symbol to indicate that its children have been observed + * via knownDirectSubclasses. Children added subsequently will trigger an + * error to indicate that the earlier observation was incomplete. + */ + case object KnownDirectSubclassesCalled extends PlainAttachment } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 3b9ee9048a..6116952c70 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -110,6 +110,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => def knownDirectSubclasses = { // See `getFlag` to learn more about the `isThreadsafe` call in the body of this method. if (!isCompilerUniverse && !isThreadsafe(purpose = AllOps)) initialize + + enclosingPackage.info.decls.foreach { sym => + if(sourceFile == sym.sourceFile) { + sym.rawInfo.forceDirectSuperclasses + } + } + + if(!isPastTyper) + updateAttachment(KnownDirectSubclassesCalled) + children } @@ -3351,7 +3361,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => private[this] var childSet: Set[Symbol] = Set() override def children = childSet - override def addChild(sym: Symbol) { childSet = childSet + sym } + override def addChild(sym: Symbol) { + if(!isPastTyper && hasAttachment[KnownDirectSubclassesCalled.type] && !childSet.contains(sym)) + globalError(s"knownDirectSubclasses of ${this.name} observed before subclass ${sym.name} registered") + + childSet = childSet + sym + } def anonOrRefinementString = { if (hasCompleteInfo) { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 9697e16da7..3a645616eb 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -310,6 +310,11 @@ trait Types /** If this is a lazy type, assign a new type to `sym`. */ def complete(sym: Symbol) {} + /** If this is a lazy type corresponding to a subclass add it to its + * parents children + */ + def forceDirectSuperclasses: Unit = () + /** The term symbol associated with the type * Note that the symbol of the normalized type is returned (@see normalize) */ diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 7725e4a2f0..8481cd8996 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -41,6 +41,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.ForAttachment this.SyntheticUnitAttachment this.SubpatternsAttachment + this.KnownDirectSubclassesCalled this.noPrint this.typeDebug this.Range -- cgit v1.2.3