diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala | 25 | ||||
-rw-r--r-- | src/library/scala/runtime/ScalaRunTime.scala | 7 | ||||
-rw-r--r-- | test/files/run/t2867.scala | 15 | ||||
-rw-r--r-- | test/pending/pos/t2867.scala | 1 |
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[_]*) |