diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-02-04 15:55:59 +0100 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-02-10 10:58:58 -0800 |
commit | 4a8edc03653cb0f6b6ed1cdea1779a19df20f8f5 (patch) | |
tree | a2504af682ddcd74d8050bbf26639b5c58b7c636 /src | |
parent | b0f81ed35a45fffb9d0761299013d9d5f324ade6 (diff) | |
download | scala-4a8edc03653cb0f6b6ed1cdea1779a19df20f8f5.tar.gz scala-4a8edc03653cb0f6b6ed1cdea1779a19df20f8f5.tar.bz2 scala-4a8edc03653cb0f6b6ed1cdea1779a19df20f8f5.zip |
SI-8129 Make Object#== override Any#==
And the same for !=
If we tried to declare these signatures in non-fictional classes,
we would be chastised about collapsing into the "same signature after
erasure".
This will have an influence of typing, as the typechecking of
arguments is sensitive to overloading: if multiple variants are
feasible, the argument will be typechecked with a wildcard expected
type. So people inspecting the types of the arguments to `==` before
this change might have seen an interesting type for
`if (true) x else y`, but now the `If` will have type `Any`, as we
don't need to calculate the LUB.
I've left a TODO to note that we should really make `Any#{==, !=}`
non-final and include a final override in `AnyVal`. But I don't think
that is particularly urgent.
Diffstat (limited to 'src')
-rw-r--r-- | src/library-aux/scala/AnyRef.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 13 |
2 files changed, 12 insertions, 5 deletions
diff --git a/src/library-aux/scala/AnyRef.scala b/src/library-aux/scala/AnyRef.scala index 362fbcf0f5..8c1862e729 100644 --- a/src/library-aux/scala/AnyRef.scala +++ b/src/library-aux/scala/AnyRef.scala @@ -76,8 +76,8 @@ trait AnyRef extends Any { * @param arg0 the object to compare against this object for equality. * @return `true` if the receiver object is equivalent to the argument; `false` otherwise. */ - final def ==(that: AnyRef): Boolean = - if (this eq null) that eq null + final def ==(that: Any): Boolean = + if (this eq null) that.asInstanceOf[AnyRef] eq null else this equals that /** Create a copy of the receiver object. diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 7a0c70caf6..78e639fdff 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -35,7 +35,8 @@ trait Definitions extends api.StandardDefinitions { private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long): MethodSymbol = { val msym = owner.newMethod(name.encode, NoPosition, flags) val params = msym.newSyntheticValueParams(formals) - msym setInfo MethodType(params, restpe) markAllCompleted + val info = if (owner.isJavaDefined) JavaMethodType(params, restpe) else MethodType(params, restpe) + msym setInfo info markAllCompleted } private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol = owner.info.decls enter newMethod(owner, name, formals, restpe, flags) @@ -904,8 +905,14 @@ trait Definitions extends api.StandardDefinitions { existentialAbstraction(clazz.unsafeTypeParams, clazz.tpe_*) // members of class scala.Any + + // TODO these aren't final! They are now overriden in AnyRef/Object. Prior to the fix + // for SI-8129, they were actually *overloaded* by the members in AnyRef/Object. + // We should unfinalize these, override in AnyValClass, and make the overrides final. + // Refchecks never actually looks at these, so its just for consistency. lazy val Any_== = enterNewMethod(AnyClass, nme.EQ, AnyTpe :: Nil, BooleanTpe, FINAL) lazy val Any_!= = enterNewMethod(AnyClass, nme.NE, AnyTpe :: Nil, BooleanTpe, FINAL) + lazy val Any_equals = enterNewMethod(AnyClass, nme.equals_, AnyTpe :: Nil, BooleanTpe) lazy val Any_hashCode = enterNewMethod(AnyClass, nme.hashCode_, Nil, IntTpe) lazy val Any_toString = enterNewMethod(AnyClass, nme.toString_, Nil, StringTpe) @@ -1012,8 +1019,8 @@ trait Definitions extends api.StandardDefinitions { // members of class java.lang.{ Object, String } lazy val Object_## = enterNewMethod(ObjectClass, nme.HASHHASH, Nil, IntTpe, FINAL) - lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, AnyRefTpe :: Nil, BooleanTpe, FINAL) - lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, AnyRefTpe :: Nil, BooleanTpe, FINAL) + lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, AnyTpe :: Nil, BooleanTpe, FINAL) + lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, AnyTpe :: Nil, BooleanTpe, FINAL) lazy val Object_eq = enterNewMethod(ObjectClass, nme.eq, AnyRefTpe :: Nil, BooleanTpe, FINAL) lazy val Object_ne = enterNewMethod(ObjectClass, nme.ne, AnyRefTpe :: Nil, BooleanTpe, FINAL) lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass, nme.isInstanceOf_Ob, FINAL | SYNTHETIC | ARTIFACT)(_ => BooleanTpe) |