Skip to content

Commit

Permalink
Deprecate numeric widening of Numeric Literals which are not represen…
Browse files Browse the repository at this point in the history
…table with Float/Double
  • Loading branch information
fabianpage committed Feb 26, 2020
1 parent b1550dd commit e88a7cb
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/reflect/scala/reflect/internal/Constants.scala
Expand Up @@ -63,7 +63,10 @@ trait Constants extends api.Constants {
def isCharRange: Boolean = isIntRange && Char.MinValue <= intValue && intValue <= Char.MaxValue
def isIntRange: Boolean = ByteTag <= tag && tag <= IntTag
def isLongRange: Boolean = ByteTag <= tag && tag <= LongTag
def isFloatRange: Boolean = ByteTag <= tag && tag <= FloatTag
// Float has a Fraction of 23 Bits + 1 implicit leading Bit so the total precision is 24 Bit (see https://en.wikipedia.org/wiki/Single-precision_floating-point_format)
def isFloatRepresentable: Boolean = ByteTag <= tag && tag <= FloatTag && (tag != IntTag && tag != LongTag || longValue <= (1L << 24) && longValue >= -(1L << 24))
// Double has a Fraction of 53 Bits + 1 implicit leading Bit => 54 Bit
def isDoubleRepresentable: Boolean = ByteTag <= tag && tag <= DoubleTag && (tag != LongTag || longValue <= (1L << 54) && longValue >= -(1L << 54))
def isNumeric: Boolean = ByteTag <= tag && tag <= DoubleTag
def isNonUnitAnyVal = BooleanTag <= tag && tag <= DoubleTag
def isSuitableLiteralType = BooleanTag <= tag && tag <= NullTag
Expand Down Expand Up @@ -218,9 +221,9 @@ trait Constants extends api.Constants {
Constant(intValue)
else if (target == LongClass && isLongRange)
Constant(longValue)
else if (target == FloatClass && isFloatRange)
else if (target == FloatClass && isFloatRepresentable)
Constant(floatValue)
else if (target == DoubleClass && isNumeric)
else if (target == DoubleClass && isDoubleRepresentable)
Constant(doubleValue)
else
null
Expand Down
20 changes: 19 additions & 1 deletion test/files/neg/deprecated_widening.check
Expand Up @@ -7,6 +7,24 @@ deprecated_widening.scala:7: warning: Automatic conversion from Long to Float is
deprecated_widening.scala:8: warning: Automatic conversion from Long to Double is deprecated (since 2.13.1) because it loses precision. Write `.toDouble` instead.
val l_d: Double = l // deprecated
^
deprecated_widening.scala:23: warning: Automatic conversion from Long to Float is deprecated (since 2.13.1) because it loses precision. Write `.toFloat` instead.
val truncatedPosFloat:Float = 16777217L // deprecated
^
deprecated_widening.scala:25: warning: Automatic conversion from Long to Float is deprecated (since 2.13.1) because it loses precision. Write `.toFloat` instead.
val truncatedNegFloat: Float = - 16777217L // deprecated
^
deprecated_widening.scala:28: warning: Automatic conversion from Int to Float is deprecated (since 2.13.1) because it loses precision. Write `.toFloat` instead.
val truncatedPosFloatI:Float = 16777217 // deprecated
^
deprecated_widening.scala:30: warning: Automatic conversion from Int to Float is deprecated (since 2.13.1) because it loses precision. Write `.toFloat` instead.
val truncatedNegFloatI: Float = - 16777217 // deprecated
^
deprecated_widening.scala:33: warning: Automatic conversion from Long to Double is deprecated (since 2.13.1) because it loses precision. Write `.toDouble` instead.
val truncatedPosDouble:Double = 18014398509481985L // deprecated
^
deprecated_widening.scala:35: warning: Automatic conversion from Long to Double is deprecated (since 2.13.1) because it loses precision. Write `.toDouble` instead.
val truncatedNegDouble: Double = - 18014398509481985L // deprecated
^
deprecated_widening.scala:12: warning: method int2float in object Int is deprecated (since 2.13.1): Implicit conversion from Int to Float is dangerous because it loses precision. Write `.toFloat` instead.
implicitly[Int => Float] // deprecated
^
Expand All @@ -17,5 +35,5 @@ deprecated_widening.scala:15: warning: method long2double in object Long is depr
implicitly[Long => Double] // deprecated
^
error: No warnings can be incurred under -Werror.
6 warnings
12 warnings
1 error
15 changes: 15 additions & 0 deletions test/files/neg/deprecated_widening.scala
Expand Up @@ -18,4 +18,19 @@ object Test {
// don't leak silent warning from float conversion
val n = 42
def clean = n max 27

val posFloat:Float = 16777216L // OK
val truncatedPosFloat:Float = 16777217L // deprecated
val negFloat: Float = - 16777216L // OK
val truncatedNegFloat: Float = - 16777217L // deprecated

val posFloatI:Float = 16777216 // OK
val truncatedPosFloatI:Float = 16777217 // deprecated
val negFloatI: Float = - 16777216 // OK
val truncatedNegFloatI: Float = - 16777217 // deprecated

val posDouble:Double = 18014398509481984L// OK
val truncatedPosDouble:Double = 18014398509481985L // deprecated
val negDouble: Double = - 18014398509481984L // OK
val truncatedNegDouble: Double = - 18014398509481985L // deprecated
}

0 comments on commit e88a7cb

Please sign in to comment.