Skip to content

Replace package object compiletime by top-level definitions; move compiletime.S to compiletime.ops.int.S #11745

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 2 commits into from
Mar 17, 2021
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
2 changes: 1 addition & 1 deletion community-build/community-projects/scodec
38 changes: 19 additions & 19 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,15 @@ class Definitions {

@tu lazy val ScalaXmlPackageClass: Symbol = getPackageClassIfDefined("scala.xml")

@tu lazy val CompiletimePackageObject: Symbol = requiredModule("scala.compiletime.package")
@tu lazy val Compiletime_codeOf: Symbol = CompiletimePackageObject.requiredMethod("codeOf")
@tu lazy val Compiletime_erasedValue : Symbol = CompiletimePackageObject.requiredMethod("erasedValue")
@tu lazy val Compiletime_uninitialized: Symbol = CompiletimePackageObject.requiredMethod("uninitialized")
@tu lazy val Compiletime_error : Symbol = CompiletimePackageObject.requiredMethod(nme.error)
@tu lazy val Compiletime_requireConst : Symbol = CompiletimePackageObject.requiredMethod("requireConst")
@tu lazy val Compiletime_constValue : Symbol = CompiletimePackageObject.requiredMethod("constValue")
@tu lazy val Compiletime_constValueOpt: Symbol = CompiletimePackageObject.requiredMethod("constValueOpt")
@tu lazy val Compiletime_summonFrom : Symbol = CompiletimePackageObject.requiredMethod("summonFrom")
@tu lazy val CompiletimePackageClass: Symbol = requiredPackage("scala.compiletime").moduleClass
@tu lazy val Compiletime_codeOf: Symbol = CompiletimePackageClass.requiredMethod("codeOf")
@tu lazy val Compiletime_erasedValue : Symbol = CompiletimePackageClass.requiredMethod("erasedValue")
@tu lazy val Compiletime_uninitialized: Symbol = CompiletimePackageClass.requiredMethod("uninitialized")
@tu lazy val Compiletime_error : Symbol = CompiletimePackageClass.requiredMethod(nme.error)
@tu lazy val Compiletime_requireConst : Symbol = CompiletimePackageClass.requiredMethod("requireConst")
@tu lazy val Compiletime_constValue : Symbol = CompiletimePackageClass.requiredMethod("constValue")
@tu lazy val Compiletime_constValueOpt: Symbol = CompiletimePackageClass.requiredMethod("constValueOpt")
@tu lazy val Compiletime_summonFrom : Symbol = CompiletimePackageClass.requiredMethod("summonFrom")
@tu lazy val CompiletimeTestingPackage: Symbol = requiredPackage("scala.compiletime.testing")
@tu lazy val CompiletimeTesting_typeChecks: Symbol = CompiletimeTestingPackage.requiredMethod("typeChecks")
@tu lazy val CompiletimeTesting_typeCheckErrors: Symbol = CompiletimeTestingPackage.requiredMethod("typeCheckErrors")
Expand All @@ -241,10 +241,10 @@ class Definitions {
@tu lazy val CompiletimeTesting_ErrorKind_Parser: Symbol = CompiletimeTesting_ErrorKind.requiredMethod("Parser")
@tu lazy val CompiletimeTesting_ErrorKind_Typer: Symbol = CompiletimeTesting_ErrorKind.requiredMethod("Typer")
@tu lazy val CompiletimeOpsPackage: Symbol = requiredPackage("scala.compiletime.ops")
@tu lazy val CompiletimeOpsAny: Symbol = requiredModule("scala.compiletime.ops.any")
@tu lazy val CompiletimeOpsInt: Symbol = requiredModule("scala.compiletime.ops.int")
@tu lazy val CompiletimeOpsString: Symbol = requiredModule("scala.compiletime.ops.string")
@tu lazy val CompiletimeOpsBoolean: Symbol = requiredModule("scala.compiletime.ops.boolean")
@tu lazy val CompiletimeOpsAnyModuleClass: Symbol = requiredModule("scala.compiletime.ops.any").moduleClass
@tu lazy val CompiletimeOpsIntModuleClass: Symbol = requiredModule("scala.compiletime.ops.int").moduleClass
@tu lazy val CompiletimeOpsStringModuleClass: Symbol = requiredModule("scala.compiletime.ops.string").moduleClass
@tu lazy val CompiletimeOpsBooleanModuleClass: Symbol = requiredModule("scala.compiletime.ops.boolean").moduleClass

/** Note: We cannot have same named methods defined in Object and Any (and AnyVal, for that matter)
* because after erasure the Any and AnyVal references get remapped to the Object methods
Expand Down Expand Up @@ -1049,7 +1049,7 @@ class Definitions {
}

final def isCompiletime_S(sym: Symbol)(using Context): Boolean =
sym.name == tpnme.S && sym.owner == CompiletimePackageObject.moduleClass
sym.name == tpnme.S && sym.owner == CompiletimeOpsIntModuleClass

private val compiletimePackageAnyTypes: Set[Name] = Set(tpnme.Equals, tpnme.NotEquals)
private val compiletimePackageIntTypes: Set[Name] = Set(
Expand All @@ -1070,11 +1070,11 @@ class Definitions {
final def isCompiletimeAppliedType(sym: Symbol)(using Context): Boolean =
compiletimePackageOpTypes.contains(sym.name)
&& (
sym.owner == CompiletimePackageObject.moduleClass && sym.name == tpnme.S
|| sym.owner == CompiletimeOpsAny.moduleClass && compiletimePackageAnyTypes.contains(sym.name)
|| sym.owner == CompiletimeOpsInt.moduleClass && compiletimePackageIntTypes.contains(sym.name)
|| sym.owner == CompiletimeOpsBoolean.moduleClass && compiletimePackageBooleanTypes.contains(sym.name)
|| sym.owner == CompiletimeOpsString.moduleClass && compiletimePackageStringTypes.contains(sym.name)
isCompiletime_S(sym)
|| sym.owner == CompiletimeOpsAnyModuleClass && compiletimePackageAnyTypes.contains(sym.name)
|| sym.owner == CompiletimeOpsIntModuleClass && compiletimePackageIntTypes.contains(sym.name)
|| sym.owner == CompiletimeOpsBooleanModuleClass && compiletimePackageBooleanTypes.contains(sym.name)
|| sym.owner == CompiletimeOpsStringModuleClass && compiletimePackageStringTypes.contains(sym.name)
)

// ----- Scala-2 library patches --------------------------------------
Expand Down
14 changes: 7 additions & 7 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4059,14 +4059,14 @@ object Types {
val owner = tycon.symbol.owner
val nArgs = args.length
val constantType =
if (owner == defn.CompiletimePackageObject.moduleClass) name match {
case tpnme.S if nArgs == 1 => constantFold1(natValue, _ + 1)
case _ => None
} else if (owner == defn.CompiletimeOpsAny.moduleClass) name match {
if (defn.isCompiletime_S(tycon.symbol)) {
if (nArgs == 1) constantFold1(natValue, _ + 1)
else None
} else if (owner == defn.CompiletimeOpsAnyModuleClass) name match {
case tpnme.Equals if nArgs == 2 => constantFold2(constValue, _ == _)
case tpnme.NotEquals if nArgs == 2 => constantFold2(constValue, _ != _)
case _ => None
} else if (owner == defn.CompiletimeOpsInt.moduleClass) name match {
} else if (owner == defn.CompiletimeOpsIntModuleClass) name match {
case tpnme.Abs if nArgs == 1 => constantFold1(intValue, _.abs)
case tpnme.Negate if nArgs == 1 => constantFold1(intValue, x => -x)
case tpnme.ToString if nArgs == 1 => constantFold1(intValue, _.toString)
Expand Down Expand Up @@ -4094,10 +4094,10 @@ object Types {
case tpnme.Min if nArgs == 2 => constantFold2(intValue, _ min _)
case tpnme.Max if nArgs == 2 => constantFold2(intValue, _ max _)
case _ => None
} else if (owner == defn.CompiletimeOpsString.moduleClass) name match {
} else if (owner == defn.CompiletimeOpsStringModuleClass) name match {
case tpnme.Plus if nArgs == 2 => constantFold2(stringValue, _ + _)
case _ => None
} else if (owner == defn.CompiletimeOpsBoolean.moduleClass) name match {
} else if (owner == defn.CompiletimeOpsBooleanModuleClass) name match {
case tpnme.Not if nArgs == 1 => constantFold1(boolValue, x => !x)
case tpnme.And if nArgs == 2 => constantFold2(boolValue, _ && _)
case tpnme.Or if nArgs == 2 => constantFold2(boolValue, _ || _)
Expand Down
5 changes: 3 additions & 2 deletions docs/docs/reference/metaprogramming/inline.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,13 +381,14 @@ val intTwo: 2 = natTwo

The `scala.compiletime` package contains helper definitions that provide support for compile time operations over values. They are described in the following.

### `constValue`, `constValueOpt`, and the `S` combinator
### `constValue` and `constValueOpt`

`constValue` is a function that produces the constant value represented by a
type.

```scala
import scala.compiletime.{constValue, S}
import scala.compiletime.constValue
import scala.compiletime.ops.int.S

transparent inline def toIntC[N]: Int =
inline constValue[N] match
Expand Down
184 changes: 184 additions & 0 deletions library/src-bootstrapped/scala/compiletime/ops/int.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package scala.compiletime
package ops

object int:
/** Successor of a natural number where zero is the type 0 and successors are reduced as if the definition was
*
* ```scala
* type S[N <: Int] <: Int = N match {
* case 0 => 1
* case 1 => 2
* case 2 => 3
* ...
* case 2147483646 => 2147483647
* }
* ```
* @syntax markdown
*/
type S[N <: Int] <: Int

/** Addition of two `Int` singleton types.
* ```scala
* val sum: 2 + 2 = 4
* ```
* @syntax markdown
*/
type +[X <: Int, Y <: Int] <: Int

/** Subtraction of two `Int` singleton types.
* ```scala
* val sub: 4 - 2 = 2
* ```
* @syntax markdown
*/
type -[X <: Int, Y <: Int] <: Int

/** Multiplication of two `Int` singleton types.
* ```scala
* val mul: 4 * 2 = 8
* ```
* @syntax markdown
*/
type *[X <: Int, Y <: Int] <: Int

/** Integer division of two `Int` singleton types.
* ```scala
* val div: 5 / 2 = 2
* ```
* @syntax markdown
*/
type /[X <: Int, Y <: Int] <: Int

/** Remainder of the division of `X` by `Y`.
* ```scala
* val mod: 5 % 2 = 1
* ```
* @syntax markdown
*/
type %[X <: Int, Y <: Int] <: Int

/** Binary left shift of `X` by `Y`.
* ```scala
* val lshift: 1 << 2 = 4
* ```
* @syntax markdown
*/
type <<[X <: Int, Y <: Int] <: Int

/** Binary right shift of `X` by `Y`.
* ```scala
* val rshift: 10 >> 1 = 5
* ```
* @syntax markdown
*/
type >>[X <: Int, Y <: Int] <: Int

/** Binary right shift of `X` by `Y`, filling the left with zeros.
* ```scala
* val rshiftzero: 10 >>> 1 = 5
* ```
* @syntax markdown
*/
type >>>[X <: Int, Y <: Int] <: Int

/** Bitwise xor of `X` and `Y`.
* ```scala
* val xor: 10 ^ 30 = 20
* ```
* @syntax markdown
*/
type ^[X <: Int, Y <: Int] <: Int

/** Less-than comparison of two `Int` singleton types.
* ```scala
* val lt1: 4 < 2 = false
* val lt2: 2 < 4 = true
* ```
* @syntax markdown
*/
type <[X <: Int, Y <: Int] <: Boolean

/** Greater-than comparison of two `Int` singleton types.
* ```scala
* val gt1: 4 > 2 = true
* val gt2: 2 > 2 = false
* ```
* @syntax markdown
*/
type >[X <: Int, Y <: Int] <: Boolean

/** Greater-or-equal comparison of two `Int` singleton types.
* ```scala
* val ge1: 4 >= 2 = true
* val ge2: 2 >= 3 = false
* ```
* @syntax markdown
*/
type >=[X <: Int, Y <: Int] <: Boolean

/** Less-or-equal comparison of two `Int` singleton types.
* ```scala
* val lt1: 4 <= 2 = false
* val lt2: 2 <= 2 = true
* ```
* @syntax markdown
*/
type <=[X <: Int, Y <: Int] <: Boolean

/** Bitwise and of `X` and `Y`.
* ```scala
* val and1: BitwiseAnd[4, 4] = 4
* val and2: BitwiseAnd[10, 5] = 0
* ```
* @syntax markdown
*/
type BitwiseAnd[X <: Int, Y <: Int] <: Int

/** Bitwise or of `X` and `Y`.
* ```scala
* val or: BitwiseOr[10, 11] = 11
* ```
* @syntax markdown
*/
type BitwiseOr[X <: Int, Y <: Int] <: Int

/** Absolute value of an `Int` singleton type.
* ```scala
* val abs: Abs[-1] = 1
* ```
* @syntax markdown
*/
type Abs[X <: Int] <: Int

/** Negation of an `Int` singleton type.
* ```scala
* val neg1: Neg[-1] = 1
* val neg2: Neg[1] = -1
* ```
* @syntax markdown
*/
type Negate[X <: Int] <: Int

/** Minimum of two `Int` singleton types.
* ```scala
* val min: Min[-1, 1] = -1
* ```
* @syntax markdown
*/
type Min[X <: Int, Y <: Int] <: Int

/** Maximum of two `Int` singleton types.
* ```scala
* val max: Max[-1, 1] = 1
* ```
* @syntax markdown
*/
type Max[X <: Int, Y <: Int] <: Int

/** String conversion of an `Int` singleton type.
* ```scala
* val abs: ToString[1] = "1"
* ```
* @syntax markdown
*/
type ToString[X <: Int] <: String
Loading