summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpradel <pradel@epfl.ch>2008-04-07 07:04:55 +0000
committerpradel <pradel@epfl.ch>2008-04-07 07:04:55 +0000
commita197e61bc8068f97767a62f1bf5cf6b35ccfba86 (patch)
tree5eaeda1bd29859040f9fae9f7b25f546fd68102c
parentb6f12c08007eb558bffe6fd89a8aad3b2fab27f3 (diff)
downloadscala-a197e61bc8068f97767a62f1bf5cf6b35ccfba86.tar.gz
scala-a197e61bc8068f97767a62f1bf5cf6b35ccfba86.tar.bz2
scala-a197e61bc8068f97767a62f1bf5cf6b35ccfba86.zip
test and fix for #631
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala24
-rw-r--r--test/files/run/t0631.check3
-rw-r--r--test/files/run/t0631.scala16
3 files changed, 36 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 89b4b85cb0..dcb1ff70d9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -123,11 +123,12 @@ trait SyntheticMethods { self: Analyzer =>
/** The equality method for case classes and modules:
* def equals(that: Any) =
- * (this eq that) ||
+ * that.isInstanceOf[AnyRef] &&
+ * ((this eq that.asInstanceOf[AnyRef]) ||
* (that match {
* case this.C(this.arg_1, ..., this.arg_n) => true
* case _ => false
- * })
+ * }))
*/
def equalsMethod: Tree = {
val method = syntheticMethod(
@@ -173,11 +174,20 @@ trait SyntheticMethods { self: Analyzer =>
}
)
}
- Match(
- that,
- List(
- CaseDef(pat, guard, Literal(Constant(true))),
- CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false)))))
+ val isAnyRef = TypeApply(
+ Select(that, Any_isInstanceOf),
+ List(TypeTree(AnyRefClass.tpe)))
+ val cast = TypeApply(
+ Select(that, Any_asInstanceOf),
+ List(TypeTree(AnyRefClass.tpe)))
+ val eq_ = Apply(Select( This(clazz) , nme.eq), List(that setType AnyRefClass.tpe))
+ val match_ = Match(that, List(
+ CaseDef(pat, guard, Literal(Constant(true))),
+ CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false)))))
+ Apply(
+ Select(isAnyRef, Boolean_and),
+ List(Apply(Select(eq_, Boolean_or),
+ List(match_))))
}
}
)
diff --git a/test/files/run/t0631.check b/test/files/run/t0631.check
new file mode 100644
index 0000000000..0a7d5e4997
--- /dev/null
+++ b/test/files/run/t0631.check
@@ -0,0 +1,3 @@
+Foo.equals called
+false
+true
diff --git a/test/files/run/t0631.scala b/test/files/run/t0631.scala
new file mode 100644
index 0000000000..e64301e514
--- /dev/null
+++ b/test/files/run/t0631.scala
@@ -0,0 +1,16 @@
+object Test extends Application {
+ class Foo {
+ override def equals(that: Any) = {
+ println("Foo.equals called")
+ super.equals(that)
+ }
+ }
+
+ println(new Foo == new Foo)
+
+ case class Bar(x: Foo)
+ val b = new Bar(new Foo)
+
+ // this should not call Foo.equals, but simply compare object identiy of b
+ println(b == b)
+}