diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-07-22 12:45:42 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2015-07-23 14:32:29 +1000 |
commit | 1febfa59f79b9a4c078dc723c68e8b38dbda8c88 (patch) | |
tree | 92068fc53de8fa4ac5256f649e5efd4fe9342144 | |
parent | f6756eaaa5504538f8fa23fc37f8728e56f76908 (diff) | |
download | scala-1febfa59f79b9a4c078dc723c68e8b38dbda8c88.tar.gz scala-1febfa59f79b9a4c078dc723c68e8b38dbda8c88.tar.bz2 scala-1febfa59f79b9a4c078dc723c68e8b38dbda8c88.zip |
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.
4 files changed, 9 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index a11906ace1..00de77a8d4 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -138,7 +138,7 @@ trait TreeAndTypeAnalysis extends Debugging { if(grouped) { def enumerateChildren(sym: Symbol) = { - sym.children.toList + sym.sealedChildren.toList .sortBy(_.sealedSortName) .filterNot(x => x.isSealed && x.isAbstractClass && !isPrimitiveValueClass(x)) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala index fc632e0d0d..8bcd5e6f12 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala @@ -212,8 +212,8 @@ trait Checkable { ) /** Are all children of these symbols pairwise irreconcilable? */ def allChildrenAreIrreconcilable(sym1: Symbol, sym2: Symbol) = ( - sym1.children.toList forall (c1 => - sym2.children.toList forall (c2 => + sym1.sealedChildren.toList forall (c1 => + sym2.sealedChildren.toList forall (c2 => areIrreconcilableAsParents(c1, c2) ) ) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2dfecbaea1..1483aca55d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1694,6 +1694,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper psym addChild context.owner else pending += ParentSealedInheritanceError(parent, psym) + if (psym.isLocalToBlock && !phase.erasedTypes) + psym addChild context.owner val parentTypeOfThis = parent.tpe.dealias.typeOfThis if (!(selfType <:< parentTypeOfThis) && diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 478b1b9732..15ab97dc3f 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -980,7 +980,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => private def isNotOverridden = ( owner.isClass && ( owner.isEffectivelyFinal - || owner.isSealed && owner.children.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol)) + || (owner.isSealed && owner.sealedChildren.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol))) ) ) @@ -2495,14 +2495,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => def associatedFile: AbstractFile = enclosingTopLevelClass.associatedFile def associatedFile_=(f: AbstractFile) { abort("associatedFile_= inapplicable for " + this) } - /** If this is a sealed class, its known direct subclasses. + /** If this is a sealed or local class, its known direct subclasses. * Otherwise, the empty set. */ def children: Set[Symbol] = Set() + final def sealedChildren: Set[Symbol] = if (!isSealed) Set.empty else children /** Recursively assemble all children of this symbol. */ - def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this + final def sealedDescendants: Set[Symbol] = if (!isSealed) Set(this) else children.flatMap(_.sealedDescendants) + this @inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt @inline final def andAlso(f: Symbol => Unit): Symbol = { if (this ne NoSymbol) f(this) ; this } |