diff options
author | Paul Phillips <paulp@improving.org> | 2011-05-14 16:55:44 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-05-14 16:55:44 +0000 |
commit | b7e7cf14bb3b06cdf9c7f7a8ccfe2d3220af95c4 (patch) | |
tree | e7b88d28690b3c2c317c2fdfdba804bd09f454b7 | |
parent | 77207165674431d6c55ccab77733a483e07f01ad (diff) | |
download | scala-b7e7cf14bb3b06cdf9c7f7a8ccfe2d3220af95c4.tar.gz scala-b7e7cf14bb3b06cdf9c7f7a8ccfe2d3220af95c4.tar.bz2 scala-b7e7cf14bb3b06cdf9c7f7a8ccfe2d3220af95c4.zip |
Change Types#narrow to create an existential ra...
Change Types#narrow to create an existential rather than a refinement
type, as the comment indicated was a desirable outcome. (Definitely)
review by odersky.
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 15 |
2 files changed, 17 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala index d75670fd38..2d31281e34 100644 --- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala +++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala @@ -142,11 +142,23 @@ trait MatrixAdditions extends ast.TreeDSL { import Flags.{ MUTABLE, ABSTRACT, SEALED } private case class Combo(index: Int, sym: Symbol) { - val isBaseClass = sym.tpe.baseClasses.toSet - // is this combination covered by the given pattern? def isCovered(p: Pattern) = { - def coversSym = isBaseClass(decodedEqualsType(p.tpe).typeSymbol) + def coversSym = { + val lhs = decodedEqualsType(p.tpe) + val rhs = sym.tpe + // This logic, arrived upon after much struggle, attempts to find the + // the route through the type maze which let us issue precise exhaustiveness + // warnings against narrowed types (see test case sealed-java-enums.scala) + // while retaining the necessary pattern matching behavior that case _: List[_] => + // matches both "object Nil" and "class ::[T]". + // + // Doubtless there is a more direct/correct expression of it. + if (rhs.typeSymbol.isSingletonExistential) + lhs <:< rhs + else + rhs.baseClasses contains lhs.typeSymbol + } cond(p.tree) { case _: UnApply | _: ArrayValue => true diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 87fc2b4963..80a48e55fc 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -79,8 +79,6 @@ trait Types extends reflect.generic.Types { self: SymbolTable => private var explainSwitch = false private final val emptySymbolSet = immutable.Set.empty[Symbol] - private final val alternativeNarrow = false - private final val LogPendingSubTypesThreshold = 50 private final val LogPendingBaseTypesThreshold = 50 private final val LogVolatileThreshold = 50 @@ -317,21 +315,12 @@ trait Types extends reflect.generic.Types { self: SymbolTable => /** Map to a singleton type which is a subtype of this type. * The fallback implemented here gives - * T.narrow = (T {}).this.type + * T.narrow = T' forSome { type T' <: T with Singleton } * Overridden where we know more about where types come from. - * - * todo: change to singleton type of an existentially defined variable - * of the right type instead of making this a `this` of a refined type. */ def narrow: Type = if (phase.erasedTypes) this - else if (alternativeNarrow) { // investigate why this does not work! - val tparam = commonOwner(this) freshExistential ".type" setInfo singletonBounds(this) - tparam.tpe - } else { - val cowner = commonOwner(this) - refinedType(List(this), cowner, EmptyScope, cowner.pos).narrow - } + else commonOwner(this) freshExistential ".type" setInfo singletonBounds(this) tpe /** For a TypeBounds type, itself; * for a reference denoting an abstract type, its bounds, |