summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala25
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala7
-rw-r--r--test/files/run/t2867.scala15
-rw-r--r--test/pending/pos/t2867.scala1
5 files changed, 31 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 68c75a721a..3d969a53b4 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -152,6 +152,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
def arrayLengthMethod = getMember(ScalaRunTimeModule, "array_length")
def arrayCloneMethod = getMember(ScalaRunTimeModule, "array_clone")
def scalaRuntimeHash = getMember(ScalaRunTimeModule, "hash")
+ def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements)
// classes with special meanings
lazy val NotNullClass = getClass("scala.NotNull")
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 6a68ddc68c..042343ac16 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -180,23 +180,14 @@ trait SyntheticMethods extends ast.TreeDSL {
// returns (Apply, Bind)
def makeTrees(acc: Symbol, cpt: Type): (Tree, Bind) = {
- val varName = context.unit.fresh.newName(clazz.pos.focus, acc.name + "$")
- val (eqMethod, binding) =
- if (isRepeatedParamType(cpt)) (nme.sameElements, Star(WILD()))
- else (nme.EQ , WILD() )
-
- ((varName DOT eqMethod)(Ident(acc)), varName BIND binding)
-/** The three lines above were replaced by the following to fix #2867. But this makes lift fail, because
- * an explicitly given type paramter violates its bound. Not sure what to do here.
- *
- if (isRepeatedParamType(cpt))
- (TypeApply(varName DOT nme.sameElements, List(TypeTree(cpt.baseType(SeqClass).typeArgs.head))),
- Star(WILD()))
- else
- ((varName DOT nme.EQ): Tree,
- WILD())
- (eqMethod APPLY Ident(acc), varName BIND binding)
- */
+ val varName = context.unit.fresh.newName(clazz.pos.focus, acc.name + "$")
+ val isRepeated = isRepeatedParamType(cpt)
+ val binding = if (isRepeated) Star(WILD()) else WILD()
+ val eqMethod: Tree =
+ if (isRepeated) gen.mkRuntimeCall(nme.sameElements, List(Ident(varName), Ident(acc)))
+ else (varName DOT nme.EQ)(Ident(acc))
+
+ (eqMethod, varName BIND binding)
}
// Creates list of parameters and a guard for each
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 82573bf4b1..d04824bae1 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -179,6 +179,13 @@ object ScalaRunTime {
*/
@inline def hash(x: Any): Int = Predef.hash(x)
+ /** A helper method for constructing case class equality methods,
+ * because existential types get in the way of a clean outcome and
+ * it's performing a series of Any/Any equals comparisons anyway.
+ * See ticket #2867 for specifics.
+ */
+ def sameElements(xs1: Seq[Any], xs2: Seq[Any]) = xs1 sameElements xs2
+
/** Given any Scala value, convert it to a String.
*
* The primary motivation for this method is to provide a means for
diff --git a/test/files/run/t2867.scala b/test/files/run/t2867.scala
new file mode 100644
index 0000000000..25e55eaecd
--- /dev/null
+++ b/test/files/run/t2867.scala
@@ -0,0 +1,15 @@
+object Test {
+ case class A(l: List[_]*)
+
+ def main(args: Array[String]): Unit = {
+ /** Kind of sneaking a slightly different test in here as well as
+ * testing 2867. How subversive.
+ */
+ val xs1 = List(1, 2, 3)
+ val xs2 = List(1.0, 2.0, 3.0)
+ val xs3 = List[Any](1.0f, 2.0f, 3.0f)
+ val xs4 = List[Byte](1, 2, 3)
+
+ assert(A(List(xs1, xs2)) == A(List(xs3, xs4)))
+ }
+}
diff --git a/test/pending/pos/t2867.scala b/test/pending/pos/t2867.scala
deleted file mode 100644
index 0434a380b9..0000000000
--- a/test/pending/pos/t2867.scala
+++ /dev/null
@@ -1 +0,0 @@
-case class A(l: List[_]*)