diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Duplicators.scala | 21 | ||||
-rw-r--r-- | test/files/pos/spec-List.scala | 2 | ||||
-rw-r--r-- | test/files/run/spec-patmatch.check | 19 | ||||
-rw-r--r-- | test/files/run/spec-patmatch.flags | 1 | ||||
-rw-r--r-- | test/files/run/spec-patmatch.scala | 52 |
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) + + } + +} |