diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 15 |
2 files changed, 24 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala index fd55945d50..23944c91d9 100644 --- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala +++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala @@ -160,10 +160,20 @@ trait MatrixAdditions extends ast.TreeDSL singleType(sym.tpe.prefix, lmoc) // e.g. None, Nil else sym.tpe + /** Note to Martin should you come through this way: this + * logic looks way overcomplicated for the intention, but a little + * experimentation showed that at least most of it is serving + * some necessary purpose. It doesn't seem like much more than + * "sym.tpe matchesPattern tpe" ought to be necessary though. + * + * For the time being I tacked the matchesPattern test onto the + * end to address #3097. + */ (tpe.typeSymbol == sym) || (symtpe <:< tpe) || (symtpe.parents exists (x => cmpSymbols(x, tpe))) || // e.g. Some[Int] <: Option[&b] - ((tpe.prefix memberType sym) <:< tpe) // outer, see combinator.lexical.Scanner + ((tpe.prefix memberType sym) <:< tpe) || // outer, see combinator.lexical.Scanner + (symtpe matchesPattern tpe) } cond(p.tree) { @@ -180,18 +190,13 @@ trait MatrixAdditions extends ast.TreeDSL private def requiresExhaustive(s: Symbol) = (s hasFlag MUTABLE) && // indicates that have not yet checked exhaustivity !(s hasFlag TRANS_FLAG) && // indicates @unchecked - (s.tpe.typeSymbol hasFlag SEALED) && + (s.tpe.typeSymbol.isSealed) && { s resetFlag MUTABLE ; true } // side effects MUTABLE flag - private def sealedSymsFor(s: Symbol): Set[Symbol] = { - val kids = s.children flatMap sealedSymsFor - if (s hasFlag ABSTRACT) kids else kids + s - } - private lazy val inexhaustives: List[List[Combo]] = { val collected = for ((pv, i) <- tvars.zipWithIndex ; val sym = pv.lhs ; if requiresExhaustive(sym)) yield - i -> sealedSymsFor(sym.tpe.typeSymbol) + i -> sym.tpe.typeSymbol.sealedDescendants val folded = collected.foldRight(List[List[Combo]]())((c, xs) => { diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index d878839fea..1ab0632e50 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -24,7 +24,6 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => def symbolCount = ids // statistics val emptySymbolArray = new Array[Symbol](0) - val emptySymbolSet = Set.empty[Symbol] /** Used for deciding in the IDE whether we can interrupt the compiler */ protected var activeLocks = 0 @@ -1425,7 +1424,15 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => (if (isModule) moduleClass else toplevelClass).isFromClassFile /** If this is a sealed class, its known direct subclasses. Otherwise Set.empty */ - def children: Set[Symbol] = emptySymbolSet + def children: List[Symbol] = Nil + + /** Recursively finds all sealed descendants and returns a sorted list. */ + def sealedDescendants: List[Symbol] = { + val kids = children flatMap (_.sealedDescendants) + val all = if (this hasFlag ABSTRACT) kids else this :: kids + + all.distinct sortBy (_.sealedSortName) + } // ToString ------------------------------------------------------------------- @@ -1951,8 +1958,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => override def sourceModule = if (isModuleClass) linkedModuleOfClass else NoSymbol - private var childSet: Set[Symbol] = emptySymbolSet - override def children: Set[Symbol] = childSet + private var childSet: Set[Symbol] = Set() + override def children: List[Symbol] = childSet.toList sortBy (_.sealedSortName) override def addChild(sym: Symbol) { childSet = childSet + sym } incCounter(classSymbolCount) |