diff options
author | Som Snytt <som.snytt@gmail.com> | 2015-01-08 09:54:10 -0800 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2015-01-09 00:40:28 -0800 |
commit | 963414f6ae6b895b41cf4372b2c76cf20389b58a (patch) | |
tree | d751dd0e656615cc8ceaa627bb5d6f4d0de1db31 | |
parent | f13fc65f38821dd06da35c488f2be89efec20a4c (diff) | |
download | scala-963414f6ae6b895b41cf4372b2c76cf20389b58a.tar.gz scala-963414f6ae6b895b41cf4372b2c76cf20389b58a.tar.bz2 scala-963414f6ae6b895b41cf4372b2c76cf20389b58a.zip |
SI-8462: Integral shift Long result type corrected
Constant folding was incorrectly promoting to Long when the
operand was Long, as with other binary ops, but the result
type depends on the receiver.
Per SLS 12.2.1.
This fixes ((1 << 2L): Int) and the other shift ops and
the other integral types.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala | 20 | ||||
-rw-r--r-- | test/files/pos/t8462.scala | 11 |
2 files changed, 24 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala index 56ed0ee16c..2f4771e9d4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -75,7 +75,7 @@ abstract class ConstantFolder { case nme.AND => Constant(x.booleanValue & y.booleanValue) case nme.EQ => Constant(x.booleanValue == y.booleanValue) case nme.NE => Constant(x.booleanValue != y.booleanValue) - case _ => null + case _ => null } private def foldSubrangeOp(op: Name, x: Constant, y: Constant): Constant = op match { case nme.OR => Constant(x.intValue | y.intValue) @@ -95,14 +95,20 @@ abstract class ConstantFolder { case nme.MUL => Constant(x.intValue * y.intValue) case nme.DIV => Constant(x.intValue / y.intValue) case nme.MOD => Constant(x.intValue % y.intValue) - case _ => null + case _ => null } private def foldLongOp(op: Name, x: Constant, y: Constant): Constant = op match { case nme.OR => Constant(x.longValue | y.longValue) case nme.XOR => Constant(x.longValue ^ y.longValue) case nme.AND => Constant(x.longValue & y.longValue) - case nme.LSL => Constant(x.longValue << y.longValue) + case nme.LSL if x.tag <= IntTag + => Constant(x.intValue << y.longValue) + case nme.LSL => Constant(x.longValue << y.longValue) + case nme.LSR if x.tag <= IntTag + => Constant(x.intValue >>> y.longValue) case nme.LSR => Constant(x.longValue >>> y.longValue) + case nme.ASR if x.tag <= IntTag + => Constant(x.intValue >> y.longValue) case nme.ASR => Constant(x.longValue >> y.longValue) case nme.EQ => Constant(x.longValue == y.longValue) case nme.NE => Constant(x.longValue != y.longValue) @@ -115,7 +121,7 @@ abstract class ConstantFolder { case nme.MUL => Constant(x.longValue * y.longValue) case nme.DIV => Constant(x.longValue / y.longValue) case nme.MOD => Constant(x.longValue % y.longValue) - case _ => null + case _ => null } private def foldFloatOp(op: Name, x: Constant, y: Constant): Constant = op match { case nme.EQ => Constant(x.floatValue == y.floatValue) @@ -129,7 +135,7 @@ abstract class ConstantFolder { case nme.MUL => Constant(x.floatValue * y.floatValue) case nme.DIV => Constant(x.floatValue / y.floatValue) case nme.MOD => Constant(x.floatValue % y.floatValue) - case _ => null + case _ => null } private def foldDoubleOp(op: Name, x: Constant, y: Constant): Constant = op match { case nme.EQ => Constant(x.doubleValue == y.doubleValue) @@ -143,7 +149,7 @@ abstract class ConstantFolder { case nme.MUL => Constant(x.doubleValue * y.doubleValue) case nme.DIV => Constant(x.doubleValue / y.doubleValue) case nme.MOD => Constant(x.doubleValue % y.doubleValue) - case _ => null + case _ => null } private def foldBinop(op: Name, x: Constant, y: Constant): Constant = { @@ -162,7 +168,7 @@ abstract class ConstantFolder { case _ => null } catch { - case ex: ArithmeticException => null + case _: ArithmeticException => null } } } diff --git a/test/files/pos/t8462.scala b/test/files/pos/t8462.scala new file mode 100644 index 0000000000..6946cf8e5e --- /dev/null +++ b/test/files/pos/t8462.scala @@ -0,0 +1,11 @@ + +trait ConstantOps { + def exprs = ( + 1 << 2L : Int, // was: error: type mismatch; found : Long(4L) + 64 >> 2L : Int, // was: error: type mismatch; found : Long(4L) + 64 >>> 2L : Int, // was: error: type mismatch; found : Long(4L) + 'a' << 2L : Int, + 'a' >> 2L : Int, + 'a'>>> 2L : Int + ) +} |