diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-05-09 15:27:32 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-05-09 15:27:32 +0200 |
commit | 7523ed37d5a4eeb2664f9ddf2cad09b70aa81877 (patch) | |
tree | ee5196ad88d0be934e08441205acacafe6f39dd0 | |
parent | 7bac372a85e5a06ec147ec648caab76df704d8dc (diff) | |
parent | 1ba2d7bb967ded0c19ff2cf966c492adc12292bb (diff) | |
download | scala-7523ed37d5a4eeb2664f9ddf2cad09b70aa81877.tar.gz scala-7523ed37d5a4eeb2664f9ddf2cad09b70aa81877.tar.bz2 scala-7523ed37d5a4eeb2664f9ddf2cad09b70aa81877.zip |
Merge pull request #3719 from retronym/ticket/8546
SI-8546 Pattern matcher analysis foiled by over-widening
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala | 5 | ||||
-rw-r--r-- | test/files/neg/t6771b.check | 2 | ||||
-rw-r--r-- | test/files/neg/t6771b.scala | 2 | ||||
-rw-r--r-- | test/files/pos/t8546.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t8546.scala | 49 |
5 files changed, 54 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index 2893cbdf45..894f959319 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -149,14 +149,15 @@ trait TreeAndTypeAnalysis extends Debugging { object typeArgsToWildcardsExceptArray extends TypeMap { // SI-6771 dealias would be enough today, but future proofing with the dealiasWiden. // See neg/t6771b.scala for elaboration - def apply(tp: Type): Type = tp.dealiasWiden match { + def apply(tp: Type): Type = tp.dealias match { case TypeRef(pre, sym, args) if args.nonEmpty && (sym ne ArrayClass) => TypeRef(pre, sym, args map (_ => WildcardType)) case _ => mapOver(tp) } } - debug.patmatResult(s"checkableType($tp)")(typeArgsToWildcardsExceptArray(tp)) + val result = typeArgsToWildcardsExceptArray(tp) + debug.patmatResult(s"checkableType($tp)")(result) } // a type is "uncheckable" (for exhaustivity) if we don't statically know its subtypes (i.e., it's unsealed) diff --git a/test/files/neg/t6771b.check b/test/files/neg/t6771b.check index ba99e9178d..0c9fae533e 100644 --- a/test/files/neg/t6771b.check +++ b/test/files/neg/t6771b.check @@ -1,4 +1,4 @@ -t6771b.scala:14: error: type mismatch; +t6771b.scala:12: error: type mismatch; found : x.type (with underlying type String) required: Test.a.type b = b match { case x => x } diff --git a/test/files/neg/t6771b.scala b/test/files/neg/t6771b.scala index 78f11f7750..9723f70290 100644 --- a/test/files/neg/t6771b.scala +++ b/test/files/neg/t6771b.scala @@ -6,8 +6,6 @@ // But, to the intrepid hacker who works on this, a few notes: // You'll have to look into places in the pattern matcher that // call `dealias`, and see if they need to be `dealiasWiden`. -// For example, if `checkableType` used only `dealias`, `pos/t6671.scala` -// would fail. object Test { val a = ""; var b: a.type = a diff --git a/test/files/pos/t8546.flags b/test/files/pos/t8546.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/pos/t8546.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/pos/t8546.scala b/test/files/pos/t8546.scala new file mode 100644 index 0000000000..c39d749b4c --- /dev/null +++ b/test/files/pos/t8546.scala @@ -0,0 +1,49 @@ +package test + +class F1() { + private sealed abstract class T + private case class A(m: Int) extends T + private case class B() extends T + private case object C extends T + + // No warnings here + private def foo(t: T) = t match { + case A(m) => println("A:" + m) + case B() => println("B") + case C => println("C") + } + + def test(m: Int): Unit = { + foo(A(m)) + foo(B()) + foo(C) + } +} + +class F2[M]() { + private sealed abstract class T + private case class A(m: M) extends T + private case class B() extends T + private case object C extends T + + // match may not be exhaustive. It would fail on the following input: C + private def foo(t: T) = t match { + case A(m) => println("A:" + m) + case B() => println("B") + case C => println("C") + } + + def test(m: M): Unit = { + foo(A(m)) + foo(B()) + foo(C) + } + +} + +object Test { + def main(args: Array[String]): Unit = { + new F1().test(1) + new F2[Int]().test(1) + } +}
\ No newline at end of file |