diff options
-rw-r--r-- | src/compiler/scala/reflect/internal/Definitions.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 12 | ||||
-rw-r--r-- | test/files/pos/t5779-numeq-warn.scala | 13 |
3 files changed, 22 insertions, 4 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 0612dcdfd4..00afdd37a6 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -404,6 +404,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val JavaSerializableClass = requiredClass[java.io.Serializable] modifyInfo fixupAsAnyTrait lazy val ComparableClass = requiredClass[java.lang.Comparable[_]] modifyInfo fixupAsAnyTrait lazy val JavaCloneableClass = requiredClass[java.lang.Cloneable] + lazy val JavaNumberClass = requiredClass[java.lang.Number] lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote] lazy val RemoteExceptionClass = requiredClass[java.rmi.RemoteException] diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 4e578e3f0d..2935305c2a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1085,13 +1085,16 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R def isBoolean(s: Symbol) = unboxedValueClass(s) == BooleanClass def isUnit(s: Symbol) = unboxedValueClass(s) == UnitClass def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) + def isJavaNumeric(s: Symbol) = s isSubClass JavaNumberClass def isSpecial(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) || isMaybeValue(s) def possibleNumericCount = onSyms(_ filter (x => isNumeric(x) || isMaybeValue(x)) size) val nullCount = onSyms(_ filter (_ == NullClass) size) + var sensicality = false def nonSensibleWarning(what: String, alwaysEqual: Boolean) = { val msg = alwaysEqual == (name == nme.EQ || name == nme.eq) unit.warning(pos, "comparing "+what+" using `"+name.decode+"' will always yield " + msg) + sensicality = true } def nonSensible(pre: String, alwaysEqual: Boolean) = nonSensibleWarning(pre+"values of types "+typesString, alwaysEqual) @@ -1123,10 +1126,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R else if (!isUnit(actual) && !isMaybeValue(actual)) // () == "abc" nonSensiblyNeq() } - else if (isNumeric(receiver)) { - if (!isNumeric(actual) && !forMSIL) + else if (isNumeric(receiver) || (!forMSIL && isJavaNumeric(receiver))) { + if (!isNumeric(actual) && !forMSIL && !isJavaNumeric(actual)) if (isUnit(actual) || isBoolean(actual) || !isMaybeValue(actual)) // 5 == "abc" nonSensiblyNeq() + sensicality = true } else if (isWarnable && !isCaseEquals) { if (isNew(qual)) // new X == y @@ -1142,7 +1146,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R } // possibleNumericCount is insufficient or this will warn on e.g. Boolean == j.l.Boolean - if (isWarnable && nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) { + if (!sensicality && isWarnable && nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) { // better to have lubbed and lost def warnIfLubless(): Unit = { val common = global.lub(List(actual.tpe, receiver.tpe)) @@ -1155,7 +1159,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R if (isCaseEquals) { def thisCase = receiver.info.member(nme.equals_).owner actual.info.baseClasses.find(_.isCase) match { - case Some(p) if (p != thisCase) => nonSensible("case class ", false) + case Some(p) if p != thisCase => nonSensible("case class ", false) case None => // stronger message on (Some(1) == None) //if (receiver.isCase && receiver.isEffectivelyFinal && !(receiver isSubClass actual)) nonSensiblyNeq() diff --git a/test/files/pos/t5779-numeq-warn.scala b/test/files/pos/t5779-numeq-warn.scala new file mode 100644 index 0000000000..76ef2970fd --- /dev/null +++ b/test/files/pos/t5779-numeq-warn.scala @@ -0,0 +1,13 @@ + +object Test { + def main(args: Array[String]) { + val d: Double = (BigInt(1) << 64).toDouble + val f: Float = d.toFloat + val n: java.lang.Number = d.toFloat + assert (d == f) // ok + assert (d == n) // was: comparing values of types Double and Number using `==' will always yield false + assert (n == d) // was: Number and Double are unrelated: they will most likely never compare equal + assert (f == n) + assert (n == f) + } +} |