Skip to content

Commit 1febfa5

Browse files
committed
SI-9408 Record known subclasses of local classes
Using the same facility that we use to record subclasses of sealed classes, record the subclasses of term-owned ("local") classes. I have changed existing callers of `children` to use `sealedChildren` so we don't start using this new information in pattern matching and type pattern checkability analysis. The following commit will build on this to infer finality of local classes in the context of outer pointer elision in the constructors phase.
1 parent f6756ea commit 1febfa5

File tree

4 files changed

+9
-6
lines changed

4 files changed

+9
-6
lines changed

src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ trait TreeAndTypeAnalysis extends Debugging {
138138

139139
if(grouped) {
140140
def enumerateChildren(sym: Symbol) = {
141-
sym.children.toList
141+
sym.sealedChildren.toList
142142
.sortBy(_.sealedSortName)
143143
.filterNot(x => x.isSealed && x.isAbstractClass && !isPrimitiveValueClass(x))
144144
}

src/compiler/scala/tools/nsc/typechecker/Checkable.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ trait Checkable {
212212
)
213213
/** Are all children of these symbols pairwise irreconcilable? */
214214
def allChildrenAreIrreconcilable(sym1: Symbol, sym2: Symbol) = (
215-
sym1.children.toList forall (c1 =>
216-
sym2.children.toList forall (c2 =>
215+
sym1.sealedChildren.toList forall (c1 =>
216+
sym2.sealedChildren.toList forall (c2 =>
217217
areIrreconcilableAsParents(c1, c2)
218218
)
219219
)

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
16941694
psym addChild context.owner
16951695
else
16961696
pending += ParentSealedInheritanceError(parent, psym)
1697+
if (psym.isLocalToBlock && !phase.erasedTypes)
1698+
psym addChild context.owner
16971699
val parentTypeOfThis = parent.tpe.dealias.typeOfThis
16981700

16991701
if (!(selfType <:< parentTypeOfThis) &&

src/reflect/scala/reflect/internal/Symbols.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
980980
private def isNotOverridden = (
981981
owner.isClass && (
982982
owner.isEffectivelyFinal
983-
|| owner.isSealed && owner.children.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol))
983+
|| (owner.isSealed && owner.sealedChildren.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol)))
984984
)
985985
)
986986

@@ -2495,14 +2495,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
24952495
def associatedFile: AbstractFile = enclosingTopLevelClass.associatedFile
24962496
def associatedFile_=(f: AbstractFile) { abort("associatedFile_= inapplicable for " + this) }
24972497

2498-
/** If this is a sealed class, its known direct subclasses.
2498+
/** If this is a sealed or local class, its known direct subclasses.
24992499
* Otherwise, the empty set.
25002500
*/
25012501
def children: Set[Symbol] = Set()
2502+
final def sealedChildren: Set[Symbol] = if (!isSealed) Set.empty else children
25022503

25032504
/** Recursively assemble all children of this symbol.
25042505
*/
2505-
def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this
2506+
final def sealedDescendants: Set[Symbol] = if (!isSealed) Set(this) else children.flatMap(_.sealedDescendants) + this
25062507

25072508
@inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt
25082509
@inline final def andAlso(f: Symbol => Unit): Symbol = { if (this ne NoSymbol) f(this) ; this }

0 commit comments

Comments
 (0)