summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala21
-rw-r--r--test/files/pos/spec-List.scala2
-rw-r--r--test/files/run/spec-patmatch.check19
-rw-r--r--test/files/run/spec-patmatch.flags1
-rw-r--r--test/files/run/spec-patmatch.scala52
5 files changed, 93 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index 40cf9e82c0..7ca2ff81bb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -240,9 +240,28 @@ abstract class Duplicators extends Analyzer {
log("changed " + tree + " to " + tree1)
super.typed(atPos(tree.pos)(tree1))
+ case Match(scrut, cases) =>
+ val scrut1 = typed(scrut, EXPRmode | BYVALmode, WildcardType)
+ val scrutTpe = scrut1.tpe.widen
+ val cases1 = if (scrutTpe.isFinalType) cases filter {
+ case CaseDef(Bind(_, pat @ Typed(_, tpt)), EmptyTree, body) =>
+ // the typed pattern is not incompatible with the scrutinee type
+ scrutTpe.matchesPattern(fixType(tpt.tpe))
+ case CaseDef(Typed(_, tpt), EmptyTree, body) =>
+ // the typed pattern is not incompatible with the scrutinee type
+ scrutTpe.matchesPattern(fixType(tpt.tpe))
+ case _ => true
+ } else cases
+
+ super.typed(atPos(tree.pos)(Match(scrut, cases1)), mode, pt)
+
+ case EmptyTree =>
+ // no need to do anything, in particular, don't set the type to null, EmptyTree.tpe_= asserts
+ tree
+
case _ =>
if (tree.hasSymbol && tree.symbol != NoSymbol && (tree.symbol.owner == definitions.AnyClass)) {
- tree.symbol = NoSymbol // maybe we can find a more specific member in a subclass of Any
+ tree.symbol = NoSymbol // maybe we can find a more specific member in a subclass of Any (see AnyVal members, like ==)
}
tree.tpe = null
super.typed(tree, mode, pt)
diff --git a/test/files/pos/spec-List.scala b/test/files/pos/spec-List.scala
index ad864abd7c..9535eaa32a 100644
--- a/test/files/pos/spec-List.scala
+++ b/test/files/pos/spec-List.scala
@@ -23,7 +23,7 @@ import annotation.tailrec
* @author Martin Odersky and others
* @version 2.8
*/
-sealed abstract class List[@specialized +A] extends LinearSeq[A]
+sealed trait List[@specialized +A] extends LinearSeq[A]
with Product
with GenericTraversableTemplate[A, List]
with LinearSeqLike[A, List[A]] {
diff --git a/test/files/run/spec-patmatch.check b/test/files/run/spec-patmatch.check
new file mode 100644
index 0000000000..a6679fa1c7
--- /dev/null
+++ b/test/files/run/spec-patmatch.check
@@ -0,0 +1,19 @@
+bool
+byte
+short
+char
+int
+long
+double
+float
+default
+object instantiations:
+bool
+byte
+short
+char
+int
+long
+double
+float
+default
diff --git a/test/files/run/spec-patmatch.flags b/test/files/run/spec-patmatch.flags
new file mode 100644
index 0000000000..3a910a936c
--- /dev/null
+++ b/test/files/run/spec-patmatch.flags
@@ -0,0 +1 @@
+-Yspecialize \ No newline at end of file
diff --git a/test/files/run/spec-patmatch.scala b/test/files/run/spec-patmatch.scala
new file mode 100644
index 0000000000..92938836d8
--- /dev/null
+++ b/test/files/run/spec-patmatch.scala
@@ -0,0 +1,52 @@
+class Foo[@specialized A] {
+ def test(x: A) = println(x match {
+ case _: Boolean => "bool"
+ case _: Byte => "byte"
+ case _: Short => "short"
+ case _: Char => "char"
+ case i: Int => "int"
+ case l: Long => "long"
+ case d: Double => "double"
+ case e: Float => "float"
+ case _ => "default"
+ })
+}
+
+object Test {
+ def test[@specialized A] (x: A) = println(x match {
+ case _: Boolean => "bool"
+ case _: Byte => "byte"
+ case _: Short => "short"
+ case _: Char => "char"
+ case i: Int => "int"
+ case l: Long => "long"
+ case d: Double => "double"
+ case e: Float => "float"
+ case _ => "default"
+ })
+
+ def main(args: Array[String]) {
+ test(true)
+ test(42.toByte)
+ test(42.toShort)
+ test('b')
+ test(42)
+ test(42l)
+ test(42.0)
+ test(42.0f)
+ test(new Object)
+
+ println("object instantiations:")
+ (new Foo).test(true)
+ (new Foo).test(42.toByte)
+ (new Foo).test(42.toShort)
+ (new Foo).test('b')
+ (new Foo).test(42)
+ (new Foo).test(42l)
+ (new Foo).test(42.0)
+ (new Foo).test(42.0f)
+ (new Foo).test(new Object)
+
+ }
+
+}