diff options
author | Martin Odersky <odersky@gmail.com> | 2007-03-22 14:57:44 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-03-22 14:57:44 +0000 |
commit | 0196b0e057dcd62903b6635f53d2857ea182280a (patch) | |
tree | c88d8741a32cb20e871f56f480e7fd9bb62e66de /src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | |
parent | 2dcc3776f9ba385b9b75cefba16ea27009b6eed2 (diff) | |
download | scala-0196b0e057dcd62903b6635f53d2857ea182280a.tar.gz scala-0196b0e057dcd62903b6635f53d2857ea182280a.tar.bz2 scala-0196b0e057dcd62903b6635f53d2857ea182280a.zip |
(1) added readLong to Console.
(2) added print/read methods to Predef
(3) added warnings for non-sensical comparisons
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/RefChecks.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 4f1a9388b7..a5f6f785b9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -437,6 +437,46 @@ abstract class RefChecks extends InfoTransform { } } +// Comparison checking ------------------------------------------------------- + + def checkSensible(pos: int, fn: Tree, args: List[Tree]) = fn match { + case Select(qual, name) if (args.length == 1) => + def isNew = qual match { + case Function(_, _) + | Apply(Select(New(_), nme.CONSTRUCTOR), _) => true + case _ => false + } + name match { + case nme.EQ | nme.NE | nme.LT | nme.GT | nme.LE | nme.GE => + val formal = fn.tpe.paramTypes.head.widen.symbol + val actual = args.head.tpe.widen.symbol + val receiver = qual.tpe.widen.symbol + def nonSensibleWarning(what: String, alwaysEqual: boolean) = + unit.warning(pos, "comparing "+what+" using `"+name.decode+"' will always yield "+ + (alwaysEqual == (name == nme.EQ || name == nme.LE || name == nme.GE))) + def nonSensible(alwaysEqual: boolean) = + nonSensibleWarning("values of types "+qual.tpe.widen+" and "+args.head.tpe.widen, + alwaysEqual) + if (formal == UnitClass && actual == UnitClass) + nonSensible(true) + else if ((receiver == BooleanClass || receiver == UnitClass) && + !(receiver isSubClass actual)) + nonSensible(false) + else if (isNumericValueClass(receiver) && + !isNumericValueClass(actual) && + !(receiver isSubClass actual)) + nonSensible(false) + else if ((receiver hasFlag FINAL) && + (fn.symbol == Object_== || fn.symbol == Object_!=) && + !(receiver isSubClass actual)) + nonSensible(false) + else if (isNew && (fn.symbol == Object_== || fn.symbol == Object_!=)) + nonSensibleWarning("a fresh object", false) + case _ => + } + case _ => + } + // Transformation ------------------------------------------------------------ /* Convert a reference to a case factory of type `tpe' to a new of the class it produces. */ @@ -628,6 +668,9 @@ abstract class RefChecks extends InfoTransform { isIrrefutable(pat1, tpt.tpe)) => result = qual + case Apply(fn, args) => + checkSensible(tree.pos, fn, args) + case If(cond, thenpart, elsepart) => cond.tpe match { case ConstantType(value) => |