summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-10-05 02:59:24 +0000
committerPaul Phillips <paulp@improving.org>2010-10-05 02:59:24 +0000
commitc1f8dbca52899f87128ece2f5d137fb91206ede7 (patch)
treeb4d379010c9279f420dab36d6a706b022baf6cbb
parent4afd17d6d309ba1d64979ee9078edebc5d8e035e (diff)
downloadscala-c1f8dbca52899f87128ece2f5d137fb91206ede7.tar.gz
scala-c1f8dbca52899f87128ece2f5d137fb91206ede7.tar.bz2
scala-c1f8dbca52899f87128ece2f5d137fb91206ede7.zip
Somewhere along the way AnyVal stopped working ...
Somewhere along the way AnyVal stopped working as sealed. (It was still sealed but had lost its children.) Closes #3163, review by rytz.
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala7
-rw-r--r--test/files/neg/anyval-sealed.check12
-rw-r--r--test/files/neg/anyval-sealed.flags1
-rw-r--r--test/files/neg/anyval-sealed.scala6
6 files changed, 33 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
index e2d26abf1f..6141b2333c 100644
--- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
@@ -21,6 +21,7 @@ trait MatrixAdditions extends ast.TreeDSL
import CODE._
import Debug._
import treeInfo.{ IsTrue, IsFalse }
+ import definitions.{ isValueClass }
/** The Squeezer, responsible for all the squeezing.
*/
@@ -172,11 +173,14 @@ trait MatrixAdditions extends ast.TreeDSL
private def rowCoversCombo(row: Row, combos: List[Combo]) =
row.guard.isEmpty && (combos forall (c => c isCovered row.pats(c.index)))
- private def requiresExhaustive(s: Symbol) =
+ private def requiresExhaustive(s: Symbol) = {
(s hasFlag MUTABLE) && // indicates that have not yet checked exhaustivity
!(s hasFlag TRANS_FLAG) && // indicates @unchecked
- (s.tpe.typeSymbol.isSealed) &&
- { s resetFlag MUTABLE ; true } // side effects MUTABLE flag
+ (s.tpe.typeSymbol.isSealed) && {
+ s resetFlag MUTABLE // side effects MUTABLE flag
+ !isValueClass(s.tpe.typeSymbol) // but make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte
+ }
+ }
private lazy val inexhaustives: List[List[Combo]] = {
val collected =
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 4b5632f7d8..77f5cbebbb 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -865,6 +865,8 @@ trait Definitions extends reflect.generic.StandardDefinitions {
Object_isInstanceOf,
Object_asInstanceOf
)
+ // AnyVal is sealed but needs to be made aware of its children
+ ScalaValueClasses foreach (AnyValClass addChild _)
if (forMSIL) {
val intType = IntClass.typeConstructor
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 7a0799a897..fb86f75a2e 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1491,10 +1491,13 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** If this is a sealed class, its known direct subclasses. Otherwise Set.empty */
def children: List[Symbol] = Nil
- /** Recursively finds all sealed descendants and returns a sorted list. */
+ /** Recursively finds all sealed descendants and returns a sorted list.
+ * Includes this symbol unless it is abstract, but as value classes are
+ * marked abstract so they can't be instantiated, they are special cased.
+ */
def sealedDescendants: List[Symbol] = {
val kids = children flatMap (_.sealedDescendants)
- val all = if (this hasFlag ABSTRACT) kids else this :: kids
+ val all = if (isAbstractClass && !isValueClass(this)) kids else this :: kids
all.distinct sortBy (_.sealedSortName)
}
diff --git a/test/files/neg/anyval-sealed.check b/test/files/neg/anyval-sealed.check
new file mode 100644
index 0000000000..48a457b496
--- /dev/null
+++ b/test/files/neg/anyval-sealed.check
@@ -0,0 +1,12 @@
+anyval-sealed.scala:2: error: match is not exhaustive!
+missing combination Byte
+missing combination Char
+missing combination Double
+missing combination Float
+missing combination Long
+missing combination Short
+missing combination Unit
+
+ def f(x: AnyVal) = x match {
+ ^
+one error found
diff --git a/test/files/neg/anyval-sealed.flags b/test/files/neg/anyval-sealed.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/anyval-sealed.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/anyval-sealed.scala b/test/files/neg/anyval-sealed.scala
new file mode 100644
index 0000000000..232a183479
--- /dev/null
+++ b/test/files/neg/anyval-sealed.scala
@@ -0,0 +1,6 @@
+class A {
+ def f(x: AnyVal) = x match {
+ case _: Boolean => 1
+ case _: Int => 2
+ }
+} \ No newline at end of file