Skip to content

Commit a522ad0

Browse files
authored
Merge pull request #11745 from dotty-staging/no-pkg-object
Replace package object compiletime by top-level definitions; move compiletime.S to compiletime.ops.int.S
2 parents f267f91 + eb7c2a8 commit a522ad0

File tree

21 files changed

+394
-44
lines changed

21 files changed

+394
-44
lines changed

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

+19-19
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")
@@ -241,10 +241,10 @@ class Definitions {
241241
@tu lazy val CompiletimeTesting_ErrorKind_Parser: Symbol = CompiletimeTesting_ErrorKind.requiredMethod("Parser")
242242
@tu lazy val CompiletimeTesting_ErrorKind_Typer: Symbol = CompiletimeTesting_ErrorKind.requiredMethod("Typer")
243243
@tu lazy val CompiletimeOpsPackage: Symbol = requiredPackage("scala.compiletime.ops")
244-
@tu lazy val CompiletimeOpsAny: Symbol = requiredModule("scala.compiletime.ops.any")
245-
@tu lazy val CompiletimeOpsInt: Symbol = requiredModule("scala.compiletime.ops.int")
246-
@tu lazy val CompiletimeOpsString: Symbol = requiredModule("scala.compiletime.ops.string")
247-
@tu lazy val CompiletimeOpsBoolean: Symbol = requiredModule("scala.compiletime.ops.boolean")
244+
@tu lazy val CompiletimeOpsAnyModuleClass: Symbol = requiredModule("scala.compiletime.ops.any").moduleClass
245+
@tu lazy val CompiletimeOpsIntModuleClass: Symbol = requiredModule("scala.compiletime.ops.int").moduleClass
246+
@tu lazy val CompiletimeOpsStringModuleClass: Symbol = requiredModule("scala.compiletime.ops.string").moduleClass
247+
@tu lazy val CompiletimeOpsBooleanModuleClass: Symbol = requiredModule("scala.compiletime.ops.boolean").moduleClass
248248

249249
/** Note: We cannot have same named methods defined in Object and Any (and AnyVal, for that matter)
250250
* because after erasure the Any and AnyVal references get remapped to the Object methods
@@ -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(
@@ -1070,11 +1070,11 @@ class Definitions {
10701070
final def isCompiletimeAppliedType(sym: Symbol)(using Context): Boolean =
10711071
compiletimePackageOpTypes.contains(sym.name)
10721072
&& (
1073-
sym.owner == CompiletimePackageObject.moduleClass && sym.name == tpnme.S
1074-
|| sym.owner == CompiletimeOpsAny.moduleClass && compiletimePackageAnyTypes.contains(sym.name)
1075-
|| sym.owner == CompiletimeOpsInt.moduleClass && compiletimePackageIntTypes.contains(sym.name)
1076-
|| sym.owner == CompiletimeOpsBoolean.moduleClass && compiletimePackageBooleanTypes.contains(sym.name)
1077-
|| sym.owner == CompiletimeOpsString.moduleClass && compiletimePackageStringTypes.contains(sym.name)
1073+
isCompiletime_S(sym)
1074+
|| sym.owner == CompiletimeOpsAnyModuleClass && compiletimePackageAnyTypes.contains(sym.name)
1075+
|| sym.owner == CompiletimeOpsIntModuleClass && compiletimePackageIntTypes.contains(sym.name)
1076+
|| sym.owner == CompiletimeOpsBooleanModuleClass && compiletimePackageBooleanTypes.contains(sym.name)
1077+
|| sym.owner == CompiletimeOpsStringModuleClass && compiletimePackageStringTypes.contains(sym.name)
10781078
)
10791079

10801080
// ----- Scala-2 library patches --------------------------------------

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -4059,14 +4059,14 @@ 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
4065-
} else if (owner == defn.CompiletimeOpsAny.moduleClass) name match {
4062+
if (defn.isCompiletime_S(tycon.symbol)) {
4063+
if (nArgs == 1) constantFold1(natValue, _ + 1)
4064+
else None
4065+
} 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, _ != _)
40684068
case _ => None
4069-
} else if (owner == defn.CompiletimeOpsInt.moduleClass) name match {
4069+
} else if (owner == defn.CompiletimeOpsIntModuleClass) name match {
40704070
case tpnme.Abs if nArgs == 1 => constantFold1(intValue, _.abs)
40714071
case tpnme.Negate if nArgs == 1 => constantFold1(intValue, x => -x)
40724072
case tpnme.ToString if nArgs == 1 => constantFold1(intValue, _.toString)
@@ -4094,10 +4094,10 @@ object Types {
40944094
case tpnme.Min if nArgs == 2 => constantFold2(intValue, _ min _)
40954095
case tpnme.Max if nArgs == 2 => constantFold2(intValue, _ max _)
40964096
case _ => None
4097-
} else if (owner == defn.CompiletimeOpsString.moduleClass) name match {
4097+
} else if (owner == defn.CompiletimeOpsStringModuleClass) name match {
40984098
case tpnme.Plus if nArgs == 2 => constantFold2(stringValue, _ + _)
40994099
case _ => None
4100-
} else if (owner == defn.CompiletimeOpsBoolean.moduleClass) name match {
4100+
} else if (owner == defn.CompiletimeOpsBooleanModuleClass) name match {
41014101
case tpnme.Not if nArgs == 1 => constantFold1(boolValue, x => !x)
41024102
case tpnme.And if nArgs == 2 => constantFold2(boolValue, _ && _)
41034103
case tpnme.Or if nArgs == 2 => constantFold2(boolValue, _ || _)

docs/docs/reference/metaprogramming/inline.md

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

377377
The [`scala.compiletime`](https://dotty.epfl.ch/api/scala/compiletime.html) package contains helper definitions that provide support for compile time operations over values. They are described in the following.
378378

379-
### `constValue`, `constValueOpt`, and the `S` combinator
379+
### `constValue` and `constValueOpt`
380380

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

384384
```scala
385-
import scala.compiletime.{constValue, S}
385+
import scala.compiletime.constValue
386+
import scala.compiletime.ops.int.S
386387

387388
transparent inline def toIntC[N]: Int =
388389
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)