summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala22
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala1
-rw-r--r--test/files/pos/bug3570.scala7
3 files changed, 21 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index 34d3423401..a24c8c01d3 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -76,20 +76,24 @@ trait TreeDSL {
else gen.mkAnd(target, other)
/** Note - calling ANY_== in the matcher caused primitives to get boxed
- * for the comparison, whereas looking up nme.EQ does not.
+ * for the comparison, whereas looking up nme.EQ does not. See #3570 for
+ * an example of how target.tpe can be non-null, yet it claims not to have
+ * a mmeber called nme.EQ. Not sure if that should happen, but we can be
+ * robust by dragging in Any regardless.
*/
def MEMBER_== (other: Tree) = {
- if (target.tpe == null) ANY_==(other)
- else fn(target, target.tpe member nme.EQ, other)
+ val opSym = if (target.tpe == null) NoSymbol else target.tpe member nme.EQ
+ if (opSym == NoSymbol) ANY_==(other)
+ else fn(target, opSym, other)
}
- def ANY_NE (other: Tree) = fn(target, nme.ne, toAnyRef(other))
def ANY_EQ (other: Tree) = fn(target, nme.eq, toAnyRef(other))
+ def ANY_NE (other: Tree) = fn(target, nme.ne, toAnyRef(other))
def ANY_== (other: Tree) = fn(target, Any_==, other)
- def ANY_>= (other: Tree) = fn(target, nme.GE, other)
- def ANY_<= (other: Tree) = fn(target, nme.LE, other)
- def OBJ_!= (other: Tree) = fn(target, Object_ne, other)
- def OBJ_EQ (other: Tree) = fn(target, nme.eq, other)
- def OBJ_NE (other: Tree) = fn(target, nme.ne, other)
+ def ANY_!= (other: Tree) = fn(target, Any_!=, other)
+ def OBJ_== (other: Tree) = fn(target, Object_==, other)
+ def OBJ_!= (other: Tree) = fn(target, Object_!=, other)
+ def OBJ_EQ (other: Tree) = fn(target, Object_eq, other)
+ def OBJ_NE (other: Tree) = fn(target, Object_ne, other)
def INT_| (other: Tree) = fn(target, getMember(IntClass, nme.OR), other)
def INT_& (other: Tree) = fn(target, getMember(IntClass, nme.AND), other)
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 77997c4565..f9e7a1bdcf 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -886,6 +886,7 @@ trait ParallelMatching extends ast.TreeDSL
}
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
diff --git a/test/files/pos/bug3570.scala b/test/files/pos/bug3570.scala
new file mode 100644
index 0000000000..8921f83b2a
--- /dev/null
+++ b/test/files/pos/bug3570.scala
@@ -0,0 +1,7 @@
+class test {
+ object Break extends Throwable
+ def break = throw Break
+ def block(x: => Unit) {
+ try { x } catch { case e: Break.type => }
+ }
+}