summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-20 22:18:21 +0000
committerPaul Phillips <paulp@improving.org>2009-10-20 22:18:21 +0000
commita021e16b5f5257d03596ad074da3d22e1865aa80 (patch)
tree15cfba5c180a75c89397d9de3c3351b1d5d708b2 /src/compiler
parent9dc0426d05b5aa36a8cd7acb998e00bbbe843dbc (diff)
downloadscala-a021e16b5f5257d03596ad074da3d22e1865aa80.tar.gz
scala-a021e16b5f5257d03596ad074da3d22e1865aa80.tar.bz2
scala-a021e16b5f5257d03596ad074da3d22e1865aa80.zip
Implementation of martin's suggested fix for #1...
Implementation of martin's suggested fix for #1503.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index c5fd840973..ba7eac7ea0 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -560,7 +560,7 @@ trait ParallelMatching extends ast.TreeDSL
j -> (moreSpecific :: subsumed)
lazy val casted = scrut castedTo pmatch.headType
- lazy val cond = condition(checkErroneous(casted), scrut)
+ lazy val cond = condition(checkErroneous(casted), scrut, head.boundVariables.nonEmpty)
private def isAnyMoreSpecific = yeses exists (x => !x.moreSpecific.isEmpty)
lazy val (subtests, subtestVars) =
@@ -803,17 +803,17 @@ trait ParallelMatching extends ast.TreeDSL
/** returns the condition in "if (cond) k1 else k2"
*/
- final def condition(tpe: Type, scrut: Scrutinee): Tree = {
+ final def condition(tpe: Type, scrut: Scrutinee, isBound: Boolean): Tree = {
assert(scrut.isDefined)
- val cond = handleOuter(condition(tpe, scrut.id))
+ val cond = handleOuter(condition(tpe, scrut.id, isBound))
if (!needsOuterTest(tpe, scrut.tpe, owner)) cond
else addOuterCondition(cond, tpe, scrut.id)
}
- final def condition(tpe: Type, scrutTree: Tree): Tree = {
+ final def condition(tpe: Type, scrutTree: Tree, isBound: Boolean): Tree = {
assert((tpe ne NoType) && (scrutTree.tpe ne NoType))
- def useEqTest = tpe.termSymbol.isModule || (tpe.prefix eq NoPrefix)
+ def useEqTest = tpe.termSymbol.isModule || (tpe.prefix eq NoPrefix)
// case SingleType(_, _) | ThisType(_) | SuperType(_, _) =>
// val cmpOp = if (targ.tpe <:< AnyValClass.tpe) Any_equals else Object_eq
@@ -824,7 +824,16 @@ trait ParallelMatching extends ast.TreeDSL
case v @ Constant(null) if scrutTree.tpe.isAnyRef => scrutTree ANY_EQ NULL
case v => scrutTree MEMBER_== Literal(v)
}
- case _: SingletonType if useEqTest => REF(tpe.termSymbol) MEMBER_== scrutTree
+ case _: SingletonType if useEqTest =>
+ val eqTest = REF(tpe.termSymbol) MEMBER_== scrutTree
+ // See ticket #1503 for the motivation behind checking for a binding.
+ // The upshot is that it is unsound to assume equality means the right
+ // type, but if the value doesn't appear on the right hand side of the
+ // match that's unimportant; so we add an instance check only if there
+ // is a binding.
+ if (isBound) eqTest AND (scrutTree IS tpe.widen)
+ else eqTest
+
case _ if scrutTree.tpe <:< tpe && tpe.isAnyRef => scrutTree OBJ_!= NULL
case _ => scrutTree IS tpe
})