From 8d537a13999878673b8d18c2429dbd6b97728e72 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 24 Mar 2013 13:56:19 +0100 Subject: SI-7294 Treat TupleN as final under -Xfuture For the purposes of checkability warnings. This will warn in case of: scala> (1, 2) match { case Seq() => 0; case _ => 1 } res9: Int = 1 Given how often Tuples are used as scrutinees, this is a highly desirable place to warn. I was orginally going to unlock this under -Xlint, and could be easily convinced to go that way, given that -Xfuture is a less popular option. --- src/compiler/scala/tools/nsc/typechecker/Checkable.scala | 11 +++++++++-- test/files/neg/t7294.check | 6 ++++++ test/files/neg/t7294.flags | 1 + test/files/neg/t7294.scala | 5 +++++ test/files/pos/t7294.scala | 6 ++++++ 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/files/neg/t7294.check create mode 100644 test/files/neg/t7294.flags create mode 100644 test/files/neg/t7294.scala create mode 100644 test/files/pos/t7294.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala index 88bfa6099d..026f5f7bc8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala @@ -195,11 +195,18 @@ trait Checkable { * so I will consult with moors about the optimal time to be doing this. */ def areIrreconcilableAsParents(sym1: Symbol, sym2: Symbol): Boolean = areUnrelatedClasses(sym1, sym2) && ( - sym1.initialize.isEffectivelyFinal // initialization important - || sym2.initialize.isEffectivelyFinal + isEffectivelyFinal(sym1) // initialization important + || isEffectivelyFinal(sym2) || !sym1.isTrait && !sym2.isTrait || sym1.isSealed && sym2.isSealed && allChildrenAreIrreconcilable(sym1, sym2) && !currentRun.compiles(sym1) && !currentRun.compiles(sym2) ) + private def isEffectivelyFinal(sym: Symbol): Boolean = ( + // initialization important + sym.initialize.isEffectivelyFinal || ( + settings.future.value && isTupleSymbol(sym) // SI-7294 step into the future and treat TupleN as final. + ) + ) + def isNeverSubClass(sym1: Symbol, sym2: Symbol) = areIrreconcilableAsParents(sym1, sym2) private def isNeverSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[Symbol]): Boolean = /*logResult(s"isNeverSubArgs($tps1, $tps2, $tparams)")*/ { diff --git a/test/files/neg/t7294.check b/test/files/neg/t7294.check new file mode 100644 index 0000000000..f15289c1c0 --- /dev/null +++ b/test/files/neg/t7294.check @@ -0,0 +1,6 @@ +t7294.scala:4: warning: fruitless type test: a value of type (Int, Int) cannot also be a Seq[A] + (1, 2) match { case Seq() => 0; case _ => 1 } + ^ +error: No warnings can be incurred under -Xfatal-warnings. +one warning found +one error found diff --git a/test/files/neg/t7294.flags b/test/files/neg/t7294.flags new file mode 100644 index 0000000000..3f3381a45b --- /dev/null +++ b/test/files/neg/t7294.flags @@ -0,0 +1 @@ +-Xfuture -Xfatal-warnings diff --git a/test/files/neg/t7294.scala b/test/files/neg/t7294.scala new file mode 100644 index 0000000000..335d071124 --- /dev/null +++ b/test/files/neg/t7294.scala @@ -0,0 +1,5 @@ +object Test { + // Treat TupleN as final under -Xfuture for the for the purposes + // of the "fruitless type test" warning. + (1, 2) match { case Seq() => 0; case _ => 1 } +} diff --git a/test/files/pos/t7294.scala b/test/files/pos/t7294.scala new file mode 100644 index 0000000000..ccac2b1400 --- /dev/null +++ b/test/files/pos/t7294.scala @@ -0,0 +1,6 @@ +object Test { + // no fruitless warning as Tuple2 isn't (yet) final. + // The corresponding `neg` test will treat it as final + // for the purposes of these tests under -Xfuture. + (1, 2) match { case Seq() => 0; case _ => 1 } +} -- cgit v1.2.3