Skip to content

Commit 96d5315

Browse files
Add compiletime.ops.string.CharAt
1 parent 8d3083b commit 96d5315

File tree

5 files changed

+34
-1
lines changed

5 files changed

+34
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ class Definitions {
11221122
)
11231123
private val compiletimePackageBooleanTypes: Set[Name] = Set(tpnme.Not, tpnme.Xor, tpnme.And, tpnme.Or)
11241124
private val compiletimePackageStringTypes: Set[Name] = Set(
1125-
tpnme.Plus, tpnme.Length, tpnme.Substring, tpnme.Matches
1125+
tpnme.Plus, tpnme.Length, tpnme.Substring, tpnme.Matches, tpnme.CharAt
11261126
)
11271127
private val compiletimePackageOpTypes: Set[Name] =
11281128
Set(tpnme.S)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ object StdNames {
234234
final val Plus: N = "+"
235235
final val S: N = "S"
236236
final val Substring: N = "Substring"
237+
final val CharAt: N = "CharAt"
237238
final val Times: N = "*"
238239
final val ToInt: N = "ToInt"
239240
final val ToLong: N = "ToLong"

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4435,6 +4435,8 @@ object Types {
44354435
case tpnme.Matches => constantFold2(stringValue, _ matches _)
44364436
case tpnme.Substring =>
44374437
constantFold3(stringValue, intValue, intValue, (s, b, e) => s.substring(b, e))
4438+
case tpnme.CharAt =>
4439+
constantFold2AB(stringValue, intValue, _ charAt _)
44384440
case _ => None
44394441
} else if (owner == defn.CompiletimeOpsBooleanModuleClass) name match {
44404442
case tpnme.Not => constantFold1(boolValue, x => !x)

library/src/scala/compiletime/ops/string.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,14 @@ object string:
4343
*/
4444
@experimental
4545
type Matches[+S <: String, +Regex <: String] <: Boolean
46+
47+
/** Returns the Char type at the specified index.
48+
* An index ranges from 0 to Length[S] - 1. The first Char of
49+
* the sequence is at index 0, the next at index 1, and so on.
50+
* ```scala
51+
* val c: CharAt["hello", 0] = 'h'
52+
* ```
53+
* @syntax markdown
54+
*/
55+
@experimental
56+
type CharAt[+S <: String, +Idx <: Int] <: Char

tests/neg/singleton-ops-string.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,23 @@ object Test {
1515

1616
val t9: Matches["hamburger", "ham.*"] = true
1717
val t10: Matches["hamburger", "ham.*"] = false // error
18+
19+
val t11: CharAt["String", 0] = 'S'
20+
val t12: CharAt["String", 1] = 't'
21+
val t13: CharAt["String", 2] = '!' // error
22+
// ^^^
23+
// Found: ('!' : Char)
24+
// Required: ('r' : Char)
25+
val t14: CharAt["String", 3] = '!' // error
26+
// ^^^
27+
// Found: ('!' : Char)
28+
// Required: ('i' : Char)
29+
val t15: CharAt["String", 4] = 'n'
30+
val t16: CharAt["String", 5] = 'g'
31+
val t17: CharAt["String", 6] = '!' // error
32+
// ^
33+
// String index out of range: 6
34+
val t18: CharAt["String", -1] = '?' // error
35+
// ^
36+
// String index out of range: -1
1837
}

0 commit comments

Comments
 (0)