diff options
4 files changed, 34 insertions, 28 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index d2cc5d66ce..29dc359287 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -248,6 +248,7 @@ trait StdNames requires SymbolTable { val eq = newTermName("eq") val equals_ = newTermName("equals") val _equals = newTermName("_equals") + val _equalsWithVarArgs = newTermName("_equalsWithVarArgs") val ex = newTermName("ex") val fail = newTermName("fail") val false_ = newTermName("false") diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index bdb02e2803..f8b11f164f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -93,7 +93,9 @@ trait SyntheticMethods requires Analyzer { } def equalsMethod: Tree = { - val target = getMember(ScalaRunTimeModule, nme._equals) + val constrParamTypes = clazz.primaryConstructor.tpe.paramTypes + val hasVarArgs = !constrParamTypes.isEmpty && constrParamTypes.last.symbol == RepeatedParamClass + val target = getMember(ScalaRunTimeModule, if (hasVarArgs) nme._equalsWithVarArgs else nme._equals) val paramtypes = if (target.tpe.paramTypes.isEmpty) List() else target.tpe.paramTypes.tail @@ -204,7 +206,7 @@ trait SyntheticMethods requires Analyzer { } else { if (!hasImplementation(nme.hashCode_)) ts += forwardingMethod(nme.hashCode_) if (!hasImplementation(nme.toString_)) ts += forwardingMethod(nme.toString_) - if (!hasImplementation(nme.equals_)) ts += equalsMethod //forwardingMethod(nme.equals_) + if (!hasImplementation(nme.equals_)) ts += equalsMethod } if (!hasDirectImplementation(nme.productPrefix)) ts += productPrefixMethod diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 73adb07d23..75a0229869 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -574,14 +574,14 @@ trait Typers requires Analyzer { } } else if (settings.Xunapply.value) { /*unapply (5.3beta) */ // fix symbol -- we are using the module not the class - val consp = if(clazz.isModule) clazz else { + val consp = if (clazz.isModule) clazz else { val obj = clazz.linkedModuleOfClass if (obj != NoSymbol) tree.setSymbol(obj) obj } if (definitions.unapplyMember(consp.tpe).exists) atPos(tree.pos) { - gen.mkAttributedRef(consp.tpe.prefix,consp) + gen.mkAttributedRef(tree.tpe.prefix,consp) } // needs member type, but member of what? ^^^ // see test/pending/pos/unapplyNeedsMemberType.scala @@ -1430,7 +1430,7 @@ trait Typers requires Analyzer { val fun1untyped = atPos(fun.pos) { Apply(Select(gen.mkAttributedRef(fun.tpe.prefix,fun.symbol), unapp), List(arg)) } - Console.println("UNAPP "+fun1untyped) + //Console.println("UNAPP "+fun+"/"+fun.tpe+" "+fun1untyped) val fun1 = typed(fun1untyped, EXPRmode, funPt) if (fun1.tpe.isErroneous) setError(tree) else { @@ -1765,23 +1765,9 @@ trait Typers requires Analyzer { /*<unapply>*/ if(settings.Xunapply.value) // unapply: in patterns, look for an object if can't find type - if(!defSym.exists && !impSym.exists && name.isTypeName && (mode & PATTERNmode) != 0) { - typedIdent(name.toTermName) match { - case t if t.symbol.isTerm /*isModule*/ => - //Console.println("special treatment for "+name+" yields "+t) - t.tpe match { - case PolyType(_,MethodType(_,_)) => - //Console.println("ugh!") - // for instance Predef.Pair - //Console.println("no special treatment for "+name) - case _ => - //return t - defSym = t.symbol - } - case _ => - Console.println("no special treatment for "+name) - // when can this happen? - } + if (!defSym.exists && !impSym.exists && name.isTypeName && (mode & PATTERNmode) != 0) { + val mod = typedIdent(name.toTermName) + return tree setSymbol mod.symbol setType mod.tpe } /*</unapply>*/ diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 1ac8180a5e..ac6a1c28f7 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -93,16 +93,33 @@ object ScalaRunTime { def _equals(x: Product, y: Any): Boolean = y match { case y1: Product if x.arity == y1.arity => - /*(x.getClass() eq y1.getClass() &&*/ { - val arity = x.arity; - var i = 0; - while (i < arity && x.element(i) == y1.element(i)) - i = i + 1; - i == arity + val arity = x.arity; + var i = 0; + while (i < arity && x.element(i) == y1.element(i)) + i = i + 1; + i == arity + case _ => + false + } + + def _equalsWithVarArgs(x: Product, y: Any): Boolean = y match { + case y1: Product if x.arity == y1.arity => + val arity = x.arity; + var i = 0; + while (i < arity - 1 && x.element(i) == y1.element(i)) + i = i + 1; + i == arity - 1 && { + x.element(i) match { + case xs: Seq[_] => + y1.element(i) match { + case ys: Seq[_] => xs sameElements ys + } + } } case _ => false } + //def checkDefined[T >: Null](x: T): T = // if (x == null) throw new UndefinedException else x |