-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add primitive compiletime operations on singleton types #7628
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
Changes from 11 commits
1d3e473
eabd95a
30d0a8e
b458372
cb3ab69
4d73d89
f634215
c9a296d
90696e9
9711dcc
c355424
5e287cd
7b9ccb4
da71e1d
2cab591
8c117c1
7e0a1db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package scala.compiletime | ||
|
||
import scala.annotation.infix | ||
|
||
package object ops { | ||
@infix type ==[X <: AnyVal, Y <: AnyVal] <: Boolean | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I moved them into The alternative was to duplicate them into each subpackage for each supported type, and then duplicate the constant folding code... which felt like a lot of duplication. Seeing that |
||
@infix type !=[X <: AnyVal, Y <: AnyVal] <: Boolean | ||
|
||
@infix type +[X <: Int, Y <: Int] <: Int | ||
MaximeKjaer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@infix type -[X <: Int, Y <: Int] <: Int | ||
@infix type *[X <: Int, Y <: Int] <: Int | ||
@infix type /[X <: Int, Y <: Int] <: Int | ||
@infix type %[X <: Int, Y <: Int] <: Int | ||
|
||
@infix type <[X <: Int, Y <: Int] <: Boolean | ||
@infix type >[X <: Int, Y <: Int] <: Boolean | ||
@infix type >=[X <: Int, Y <: Int] <: Boolean | ||
@infix type <=[X <: Int, Y <: Int] <: Boolean | ||
|
||
type Abs[X <: Int] <: Int | ||
type Negate[X <: Int] <: Int | ||
type Min[X <: Int, Y <: Int] <: Int | ||
type Max[X <: Int, Y <: Int] <: Int | ||
type ToString[X <: Int] <: String | ||
|
||
type ![X <: Boolean] <: Boolean | ||
@infix type ^[X <: Boolean, Y <: Boolean] <: Boolean | ||
@infix type &&[X <: Boolean, Y <: Boolean] <: Boolean | ||
@infix type ||[X <: Boolean, Y <: Boolean] <: Boolean | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import scala.compiletime.ops._ | ||
|
||
object Test { | ||
type Max2[A <: Int, B <: Int] <: Int = (A < B) match { | ||
case true => B | ||
case false => A | ||
} | ||
val t0: Max2[-1, 10] = 10 | ||
val t1: Max2[4, 2] = 4 | ||
val t2: Max2[2, 2] = 1 // error | ||
val t3: Max2[-1, -1] = 0 // error | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import scala.compiletime.ops._ | ||
|
||
object Test { | ||
type GCD[A <: Int, B <: Int] <: Int = B match { | ||
case 0 => A | ||
case _ => GCD[B, A % B] | ||
} | ||
val t0: GCD[10, 0] = 10 | ||
val t1: GCD[252, 105] = 21 | ||
val t3: GCD[105, 147] = 10 // error | ||
val t4: GCD[1, 1] = -1 // error | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import scala.compiletime.ops._ | ||
|
||
object Test { | ||
type Xor[A <: Boolean, B <: Boolean] = (A && ![B]) || (![A] && B) | ||
val t0: Xor[true, true] = false | ||
val t1: Xor[false, true] = true | ||
val t2: Xor[true, false] = false // error | ||
val t3: Xor[false, false] = true // error | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import scala.compiletime.ops._ | ||
|
||
object Test { | ||
summon[2 + 3 =:= 6 - 1] | ||
summon[1763 =:= 41 * 43] | ||
summon[2 + 2 =:= 3] // error | ||
summon[29 * 31 =:= 900] // error | ||
summon[Int <:< Int + 1] // error | ||
summon[1 + Int <:< Int] | ||
|
||
val t0: 2 + 3 = 5 | ||
val t1: 2 + 2 = 5 // error | ||
val t2: -1 + 1 = 0 | ||
val t3: -5 + -5 = -11 // error | ||
|
||
val t4: 10 * 20 = 200 | ||
val t5: 30 * 10 = 400 // error | ||
val t6: -10 * 2 = -20 | ||
val t7: -2 * -2 = 4 | ||
|
||
val t8: 10 / 2 = 5 | ||
val t9: 11 / -2 = -5 // Integer division | ||
val t10: 2 / 4 = 2 // error | ||
val t11: -1 / 0 = 1 // error | ||
|
||
val t12: 10 % 3 = 1 | ||
val t13: 12 % 2 = 1 // error | ||
val t14: 1 % -3 = 1 | ||
val t15: -3 % 0 = 0 // error | ||
|
||
val t16: 1 < 0 = false | ||
val t17: 0 < 1 = true | ||
val t18: 10 < 5 = true // error | ||
val t19: 5 < 10 = false // error | ||
|
||
val t20: 1 <= 0 = false | ||
val t21: 1 <= 1 = true | ||
val t22: 10 <= 5 = true // error | ||
val t23: 5 <= 10 = false // error | ||
|
||
val t24: 1 > 0 = true | ||
val t25: 0 > 1 = false | ||
val t26: 10 > 5 = false // error | ||
val t27: 5 > 10 = true // error | ||
|
||
val t28: 1 >= 1 = true | ||
val t29: 0 >= 1 = false | ||
val t30: 10 >= 5 = false // error | ||
val t31: 5 >= 10 = true // error | ||
|
||
val t32: 1 == 1 = true | ||
val t33: 0 == 1 = false | ||
val t34: 10 == 5 = true // error | ||
val t35: 10 == 10 = false // error | ||
|
||
val t36: 1 != 1 = false | ||
val t37: 0 != 1 = true | ||
val t38: 10 != 5 = false // error | ||
val t39: 10 != 10 = true // error | ||
|
||
val t40: Abs[0] = 0 | ||
val t41: Abs[-1] = 1 | ||
val t42: Abs[-1] = -1 // error | ||
val t43: Abs[1] = -1 // error | ||
|
||
val t44: Negate[-10] = 10 | ||
val t45: Negate[10] = -10 | ||
val t46: Negate[1] = 1 // error | ||
val t47: Negate[-1] = -1 // error | ||
|
||
val t48: Max[-1, 10] = 10 | ||
val t49: Max[4, 2] = 4 | ||
val t50: Max[2, 2] = 1 // error | ||
val t51: Max[-1, -1] = 0 // error | ||
|
||
val t52: Min[-1, 10] = -1 | ||
val t53: Min[4, 2] = 2 | ||
val t54: Min[2, 2] = 1 // error | ||
val t55: Min[-1, -1] = 0 // error | ||
|
||
val t56: true && true = true | ||
val t57: true && false = false | ||
val t58: false && true = true // error | ||
val t59: false && false = true // error | ||
|
||
val t60: true || true = true | ||
val t61: true || false = true | ||
val t62: false || true = false // error | ||
val t63: false || false = true // error | ||
|
||
val t64: ![true] = false | ||
val t65: ![false] = true | ||
val t66: ![true] = true // error | ||
val t67: ![false] = false // error | ||
|
||
val t68: ToString[213] = "213" | ||
val t69: ToString[-1] = "-1" | ||
val t70: ToString[0] = "-0" // error | ||
val t71: ToString[200] = "100" // error | ||
} |
Uh oh!
There was an error while loading. Please reload this page.