Skip to content

Commit 8e0e37f

Browse files
committed
Replace package object compiletime by top-level definitions
Also move S from scala.compiletime to scala.compiletime.ops.int where all the other type operators on Int are defined.
1 parent 619fcf1 commit 8e0e37f

File tree

21 files changed

+381
-31
lines changed

21 files changed

+381
-31
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

+10-10
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,15 @@ class Definitions {
222222

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

225-
@tu lazy val CompiletimePackageObject: Symbol = requiredModule("scala.compiletime.package")
226-
@tu lazy val Compiletime_codeOf: Symbol = CompiletimePackageObject.requiredMethod("codeOf")
227-
@tu lazy val Compiletime_erasedValue : Symbol = CompiletimePackageObject.requiredMethod("erasedValue")
228-
@tu lazy val Compiletime_uninitialized: Symbol = CompiletimePackageObject.requiredMethod("uninitialized")
229-
@tu lazy val Compiletime_error : Symbol = CompiletimePackageObject.requiredMethod(nme.error)
230-
@tu lazy val Compiletime_requireConst : Symbol = CompiletimePackageObject.requiredMethod("requireConst")
231-
@tu lazy val Compiletime_constValue : Symbol = CompiletimePackageObject.requiredMethod("constValue")
232-
@tu lazy val Compiletime_constValueOpt: Symbol = CompiletimePackageObject.requiredMethod("constValueOpt")
233-
@tu lazy val Compiletime_summonFrom : Symbol = CompiletimePackageObject.requiredMethod("summonFrom")
225+
@tu lazy val CompiletimePackageClass: Symbol = requiredPackage("scala.compiletime").moduleClass
226+
@tu lazy val Compiletime_codeOf: Symbol = CompiletimePackageClass.requiredMethod("codeOf")
227+
@tu lazy val Compiletime_erasedValue : Symbol = CompiletimePackageClass.requiredMethod("erasedValue")
228+
@tu lazy val Compiletime_uninitialized: Symbol = CompiletimePackageClass.requiredMethod("uninitialized")
229+
@tu lazy val Compiletime_error : Symbol = CompiletimePackageClass.requiredMethod(nme.error)
230+
@tu lazy val Compiletime_requireConst : Symbol = CompiletimePackageClass.requiredMethod("requireConst")
231+
@tu lazy val Compiletime_constValue : Symbol = CompiletimePackageClass.requiredMethod("constValue")
232+
@tu lazy val Compiletime_constValueOpt: Symbol = CompiletimePackageClass.requiredMethod("constValueOpt")
233+
@tu lazy val Compiletime_summonFrom : Symbol = CompiletimePackageClass.requiredMethod("summonFrom")
234234
@tu lazy val CompiletimeTestingPackage: Symbol = requiredPackage("scala.compiletime.testing")
235235
@tu lazy val CompiletimeTesting_typeChecks: Symbol = CompiletimeTestingPackage.requiredMethod("typeChecks")
236236
@tu lazy val CompiletimeTesting_typeCheckErrors: Symbol = CompiletimeTestingPackage.requiredMethod("typeCheckErrors")
@@ -1049,7 +1049,7 @@ class Definitions {
10491049
}
10501050

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

10541054
private val compiletimePackageAnyTypes: Set[Name] = Set(tpnme.Equals, tpnme.NotEquals)
10551055
private val compiletimePackageIntTypes: Set[Name] = Set(

compiler/src/dotty/tools/dotc/core/Types.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -4059,9 +4059,9 @@ object Types {
40594059
val owner = tycon.symbol.owner
40604060
val nArgs = args.length
40614061
val constantType =
4062-
if (owner == defn.CompiletimePackageObject.moduleClass) name match {
4063-
case tpnme.S if nArgs == 1 => constantFold1(natValue, _ + 1)
4064-
case _ => None
4062+
if (defn.isCompiletime_S(tycon.symbol)) {
4063+
if (nArgs == 1) constantFold1(natValue, _ + 1)
4064+
else None
40654065
} else if (owner == defn.CompiletimeOpsAnyModuleClass) name match {
40664066
case tpnme.Equals if nArgs == 2 => constantFold2(constValue, _ == _)
40674067
case tpnme.NotEquals if nArgs == 2 => constantFold2(constValue, _ != _)

docs/docs/reference/metaprogramming/inline.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,14 @@ val intTwo: 2 = natTwo
381381

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

384-
### `constValue`, `constValueOpt`, and the `S` combinator
384+
### `constValue` and `constValueOpt`
385385

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

389389
```scala
390-
import scala.compiletime.{constValue, S}
390+
import scala.compiletime.constValue
391+
import scala.compiletime.ops.int.S
391392

392393
transparent inline def toIntC[N]: Int =
393394
inline constValue[N] match
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package scala.compiletime
2+
package ops
3+
4+
object int:
5+
/** Successor of a natural number where zero is the type 0 and successors are reduced as if the definition was
6+
*
7+
* ```scala
8+
* type S[N <: Int] <: Int = N match {
9+
* case 0 => 1
10+
* case 1 => 2
11+
* case 2 => 3
12+
* ...
13+
* case 2147483646 => 2147483647
14+
* }
15+
* ```
16+
* @syntax markdown
17+
*/
18+
type S[N <: Int] <: Int
19+
20+
/** Addition of two `Int` singleton types.
21+
* ```scala
22+
* val sum: 2 + 2 = 4
23+
* ```
24+
* @syntax markdown
25+
*/
26+
type +[X <: Int, Y <: Int] <: Int
27+
28+
/** Subtraction of two `Int` singleton types.
29+
* ```scala
30+
* val sub: 4 - 2 = 2
31+
* ```
32+
* @syntax markdown
33+
*/
34+
type -[X <: Int, Y <: Int] <: Int
35+
36+
/** Multiplication of two `Int` singleton types.
37+
* ```scala
38+
* val mul: 4 * 2 = 8
39+
* ```
40+
* @syntax markdown
41+
*/
42+
type *[X <: Int, Y <: Int] <: Int
43+
44+
/** Integer division of two `Int` singleton types.
45+
* ```scala
46+
* val div: 5 / 2 = 2
47+
* ```
48+
* @syntax markdown
49+
*/
50+
type /[X <: Int, Y <: Int] <: Int
51+
52+
/** Remainder of the division of `X` by `Y`.
53+
* ```scala
54+
* val mod: 5 % 2 = 1
55+
* ```
56+
* @syntax markdown
57+
*/
58+
type %[X <: Int, Y <: Int] <: Int
59+
60+
/** Binary left shift of `X` by `Y`.
61+
* ```scala
62+
* val lshift: 1 << 2 = 4
63+
* ```
64+
* @syntax markdown
65+
*/
66+
type <<[X <: Int, Y <: Int] <: Int
67+
68+
/** Binary right shift of `X` by `Y`.
69+
* ```scala
70+
* val rshift: 10 >> 1 = 5
71+
* ```
72+
* @syntax markdown
73+
*/
74+
type >>[X <: Int, Y <: Int] <: Int
75+
76+
/** Binary right shift of `X` by `Y`, filling the left with zeros.
77+
* ```scala
78+
* val rshiftzero: 10 >>> 1 = 5
79+
* ```
80+
* @syntax markdown
81+
*/
82+
type >>>[X <: Int, Y <: Int] <: Int
83+
84+
/** Bitwise xor of `X` and `Y`.
85+
* ```scala
86+
* val xor: 10 ^ 30 = 20
87+
* ```
88+
* @syntax markdown
89+
*/
90+
type ^[X <: Int, Y <: Int] <: Int
91+
92+
/** Less-than comparison of two `Int` singleton types.
93+
* ```scala
94+
* val lt1: 4 < 2 = false
95+
* val lt2: 2 < 4 = true
96+
* ```
97+
* @syntax markdown
98+
*/
99+
type <[X <: Int, Y <: Int] <: Boolean
100+
101+
/** Greater-than comparison of two `Int` singleton types.
102+
* ```scala
103+
* val gt1: 4 > 2 = true
104+
* val gt2: 2 > 2 = false
105+
* ```
106+
* @syntax markdown
107+
*/
108+
type >[X <: Int, Y <: Int] <: Boolean
109+
110+
/** Greater-or-equal comparison of two `Int` singleton types.
111+
* ```scala
112+
* val ge1: 4 >= 2 = true
113+
* val ge2: 2 >= 3 = false
114+
* ```
115+
* @syntax markdown
116+
*/
117+
type >=[X <: Int, Y <: Int] <: Boolean
118+
119+
/** Less-or-equal comparison of two `Int` singleton types.
120+
* ```scala
121+
* val lt1: 4 <= 2 = false
122+
* val lt2: 2 <= 2 = true
123+
* ```
124+
* @syntax markdown
125+
*/
126+
type <=[X <: Int, Y <: Int] <: Boolean
127+
128+
/** Bitwise and of `X` and `Y`.
129+
* ```scala
130+
* val and1: BitwiseAnd[4, 4] = 4
131+
* val and2: BitwiseAnd[10, 5] = 0
132+
* ```
133+
* @syntax markdown
134+
*/
135+
type BitwiseAnd[X <: Int, Y <: Int] <: Int
136+
137+
/** Bitwise or of `X` and `Y`.
138+
* ```scala
139+
* val or: BitwiseOr[10, 11] = 11
140+
* ```
141+
* @syntax markdown
142+
*/
143+
type BitwiseOr[X <: Int, Y <: Int] <: Int
144+
145+
/** Absolute value of an `Int` singleton type.
146+
* ```scala
147+
* val abs: Abs[-1] = 1
148+
* ```
149+
* @syntax markdown
150+
*/
151+
type Abs[X <: Int] <: Int
152+
153+
/** Negation of an `Int` singleton type.
154+
* ```scala
155+
* val neg1: Neg[-1] = 1
156+
* val neg2: Neg[1] = -1
157+
* ```
158+
* @syntax markdown
159+
*/
160+
type Negate[X <: Int] <: Int
161+
162+
/** Minimum of two `Int` singleton types.
163+
* ```scala
164+
* val min: Min[-1, 1] = -1
165+
* ```
166+
* @syntax markdown
167+
*/
168+
type Min[X <: Int, Y <: Int] <: Int
169+
170+
/** Maximum of two `Int` singleton types.
171+
* ```scala
172+
* val max: Max[-1, 1] = 1
173+
* ```
174+
* @syntax markdown
175+
*/
176+
type Max[X <: Int, Y <: Int] <: Int
177+
178+
/** String conversion of an `Int` singleton type.
179+
* ```scala
180+
* val abs: ToString[1] = "1"
181+
* ```
182+
* @syntax markdown
183+
*/
184+
type ToString[X <: Int] <: String

0 commit comments

Comments
 (0)