Skip to content

Fix 10156: Put generic number literals under a flag #10286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions compiler/src/dotty/tools/dotc/config/Feature.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import reporting.Message

object Feature:

private val dependent = "dependent".toTermName
private val namedTypeArguments = "namedTypeArguments".toTermName
private val genericNumberLiterals = "genericNumberLiterals".toTermName

/** Is `feature` enabled by by a command-line setting? The enabling setting is
*
* -language:<prefix>feature
Expand Down Expand Up @@ -58,10 +62,13 @@ object Feature:
enabled(nme.dynamics)

def dependentEnabled(using Context) =
enabled(nme.dependent, defn.LanguageExperimentalModule.moduleClass)
enabled(dependent, defn.LanguageExperimentalModule.moduleClass)

def namedTypeArgsEnabled(using Context) =
enabled(nme.namedTypeArguments, defn.LanguageExperimentalModule.moduleClass)
enabled(namedTypeArguments, defn.LanguageExperimentalModule.moduleClass)

def genericNumberLiteralsEnabled(using Context) =
enabled(genericNumberLiterals, defn.LanguageExperimentalModule.moduleClass)

def scala2ExperimentalMacroEnabled(using Context) =
enabled("macros".toTermName, defn.LanguageExperimentalModule.moduleClass)
Expand Down
2 changes: 0 additions & 2 deletions compiler/src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,6 @@ object StdNames {
val definitions: N = "definitions"
val delayedInit: N = "delayedInit"
val delayedInitArg: N = "delayedInit$body"
val dependent: N = "dependent"
val derived: N = "derived"
val derives: N = "derives"
val doubleHash: N = "doubleHash"
Expand Down Expand Up @@ -528,7 +527,6 @@ object StdNames {
val moduleClass : N = "moduleClass"
val name: N = "name"
val nameDollar: N = "$name"
val namedTypeArguments: N = "namedTypeArguments"
val ne: N = "ne"
val newFreeTerm: N = "newFreeTerm"
val newFreeType: N = "newFreeType"
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,9 @@ class Typer extends Namer
case Whole(16) => // cant parse hex literal as double
case _ => return lit(doubleFromDigits(digits))
}
else if (target.isValueType && isFullyDefined(target, ForceDegree.none)) {
else if genericNumberLiteralsEnabled
&& target.isValueType && isFullyDefined(target, ForceDegree.none)
then
// If expected type is defined with a FromDigits instance, use that one
val fromDigitsCls = tree.kind match {
case Whole(10) => defn.FromDigitsClass
Expand All @@ -645,7 +647,6 @@ class Typer extends Namer
return typed(app, pt)
case _ =>
}
}
// Otherwise convert to Int or Double according to digits format
tree.kind match {
case Whole(radix) => lit(intFromDigits(digits, radix))
Expand Down
5 changes: 5 additions & 0 deletions docs/docs/reference/changed-features/numeric-literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ layout: doc-page
title: Numeric Literals
---

**Note**: This feature is not yet part of the Scala 3 language definition. It can be made available by a language import:
```scala
import scala.language.experimental.genericNumberLiterals
```

In Scala 2, numeric literals were confined to the primitive numeric types `Int`, `Long`, `Float`, and `Double`. Scala 3 allows to write numeric literals also for user defined types. Example:
```scala
val x: Long = -10_000_000_000
Expand Down
3 changes: 3 additions & 0 deletions library/src/scalaShadowing/language.scala
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ object language {

/** Experimental support for named type arguments */
object namedTypeArguments

/** Experimental support for generic number literals */
object genericNumberLiterals
}

/** Where imported, a backwards compatibility mode for Scala2 is enabled */
Expand Down
1 change: 1 addition & 0 deletions tests/neg-macros/BigFloat/BigFloatFromDigitsImpl_1.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package test
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._

Expand Down
1 change: 1 addition & 0 deletions tests/neg-macros/BigFloat/BigFloat_1.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package test
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._

Expand Down
1 change: 1 addition & 0 deletions tests/neg-macros/GenericNumLits/EvenFromDigitsImpl_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._
import Even._
Expand Down
1 change: 1 addition & 0 deletions tests/neg-macros/GenericNumLits/Even_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._

Expand Down
1 change: 1 addition & 0 deletions tests/neg-macros/GenericNumLits/Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import language.experimental.genericNumberLiterals
object Test extends App {

val e1: Even = 1234
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._
import Even._
Expand Down
1 change: 1 addition & 0 deletions tests/neg-with-compiler/GenericNumLits/Even_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._

Expand Down
1 change: 1 addition & 0 deletions tests/neg-with-compiler/GenericNumLits/Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import language.experimental.genericNumberLiterals
object Test extends App {

val e1: Even = 1234
Expand Down
41 changes: 41 additions & 0 deletions tests/neg/genericNumbers.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import scala.util.FromDigits

object Test extends App {

val x: BigInt = 13232202002020202020202 // error
val z: BigDecimal = 132322020020.223

case class Even(n: Int)

given FromDigits[Even] {
def fromDigits(digits: String): Even = {
val intValue = digits.toInt
if (intValue % 2 == 0) Even(intValue)
else throw FromDigits.MalformedNumber()
}
}

val e: Even = 1234 // error

try {
println(123: Even) // error
} catch {
case ex: FromDigits.MalformedNumber => println("malformed")
}

x match {
case 13_232_202_002_020_202_020_202 => () // error
}
(x: Any) match {
case 13232202002020202020202: BigInt => () // error
}
x match {
case 13232202002020202020202 => assert(false) // error
case -0xaabb12345ACF12345AC => () // error
}

(e: Any) match {
case 1234: Even => // error
case _: Even =>
}
}
1 change: 1 addition & 0 deletions tests/run-macros/BigFloat/BigFloatFromDigitsImpl_1.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package test
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._

Expand Down
1 change: 1 addition & 0 deletions tests/run-macros/BigFloat/BigFloat_1.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package test
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted._

Expand Down
1 change: 1 addition & 0 deletions tests/run-macros/BigFloat/Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import test.BigFloat
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
object Test extends App {

Expand Down
1 change: 1 addition & 0 deletions tests/run/genericNumLits.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
object Test extends App {

Expand Down