From c1f8dbca52899f87128ece2f5d137fb91206ede7 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 5 Oct 2010 02:59:24 +0000 Subject: 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. --- src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala | 10 +++++++--- src/compiler/scala/tools/nsc/symtab/Definitions.scala | 2 ++ src/compiler/scala/tools/nsc/symtab/Symbols.scala | 7 +++++-- test/files/neg/anyval-sealed.check | 12 ++++++++++++ test/files/neg/anyval-sealed.flags | 1 + test/files/neg/anyval-sealed.scala | 6 ++++++ 6 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 test/files/neg/anyval-sealed.check create mode 100644 test/files/neg/anyval-sealed.flags create mode 100644 test/files/neg/anyval-sealed.scala 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 -- cgit v1.2.3