Skip to content

Commit 7d369e2

Browse files
committed
Allow into on enums
1 parent 0a7f843 commit 7d369e2

File tree

6 files changed

+145
-4
lines changed

6 files changed

+145
-4
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4266,10 +4266,13 @@ object Parsers {
42664266
private def checkAccessOnly(mods: Modifiers, where: String): Modifiers =
42674267
// We allow `infix to mark the `enum`s type as infix.
42684268
// Syntax rules disallow the soft infix modifier on `case`s.
4269-
val mods1 = mods & (AccessFlags | Enum | Infix)
4270-
if mods1 ne mods then
4269+
4270+
val flags = mods.flags.toTypeFlags
4271+
val flags1 = flags & (AccessFlags | Enum | Infix | Into).toTypeFlags
4272+
if flags1 != flags then
42714273
syntaxError(em"Only access modifiers are allowed on enum $where")
4272-
mods1
4274+
mods.withFlags(flags1)
4275+
else mods
42734276

42744277
/** EnumDef ::= id ClassConstr InheritClauses EnumBody
42754278
*/

docs/_docs/reference/enums/enums.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ The fields referenced by `Mercury` are not visible, and the fields referenced by
117117
be referenced directly (using `import Planet.*`). You must use an indirect reference,
118118
such as demonstrated with `Earth`.
119119

120+
Enum cases accept only access modifiers.
121+
Enum classes accept only access modifiers and `into` or `infix`.
122+
120123
## Deprecation of Enum Cases
121124

122125
As a library author, you may want to signal that an enum case is no longer intended for use. However you could still want to gracefully handle the removal of a case from your public API, such as special casing deprecated cases.

tests/neg/i23400.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ case class Baz(foo: MyInto[Foo])
1414

1515
given Conversion[Int, Foo] = Foo(_)
1616

17-
into enum Color: // error
17+
into enum Color: // ok
1818
case Red, Green
1919

2020
def test =

tests/neg/i5525.check

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
-- Error: tests/neg/i5525.scala:1:14 -----------------------------------------------------------------------------------
2+
1 |abstract enum Foo1 {} // error: only access modifiers allowed
3+
| ^^^^
4+
| Only access modifiers are allowed on enum definitions
5+
-- Error: tests/neg/i5525.scala:2:14 -----------------------------------------------------------------------------------
6+
2 |final enum Foo2 {} // error: only access modifiers allowed
7+
| ^^^^
8+
| Only access modifiers are allowed on enum definitions
9+
-- Error: tests/neg/i5525.scala:3:14 -----------------------------------------------------------------------------------
10+
3 |sealed enum Foo3 {} // error: only access modifiers allowed
11+
| ^^^^
12+
| Only access modifiers are allowed on enum definitions
13+
-- Error: tests/neg/i5525.scala:4:14 -----------------------------------------------------------------------------------
14+
4 |implicit enum Foo4 {} // error: only access modifiers allowed
15+
| ^^^^
16+
| Only access modifiers are allowed on enum definitions
17+
-- Error: tests/neg/i5525.scala:5:14 -----------------------------------------------------------------------------------
18+
5 |lazy enum Foo5 {} // error: only access modifiers allowed
19+
| ^^^^
20+
| Only access modifiers are allowed on enum definitions
21+
-- Error: tests/neg/i5525.scala:6:14 -----------------------------------------------------------------------------------
22+
6 |override enum Foo7 {} // error: only access modifiers allowed
23+
| ^^^^
24+
| Only access modifiers are allowed on enum definitions
25+
-- Error: tests/neg/i5525.scala:7:14 -----------------------------------------------------------------------------------
26+
7 |inline enum Foo8 {} // error: only access modifiers allowed
27+
| ^^^^
28+
| Only access modifiers are allowed on enum definitions
29+
-- Error: tests/neg/i5525.scala:8:14 -----------------------------------------------------------------------------------
30+
8 |opaque enum Foo9 {} // error: only access modifiers allowed
31+
| ^^^^
32+
| Only access modifiers are allowed on enum definitions
33+
-- Error: tests/neg/i5525.scala:11:12 ----------------------------------------------------------------------------------
34+
11 | abstract case C1() // error: only access modifiers allowed
35+
| ^^^^
36+
| Only access modifiers are allowed on enum cases
37+
-- Error: tests/neg/i5525.scala:12:12 ----------------------------------------------------------------------------------
38+
12 | final case C2() // error: only access modifiers allowed
39+
| ^^^^
40+
| Only access modifiers are allowed on enum cases
41+
-- Error: tests/neg/i5525.scala:13:12 ----------------------------------------------------------------------------------
42+
13 | sealed case C3() // error: only access modifiers allowed
43+
| ^^^^
44+
| Only access modifiers are allowed on enum cases
45+
-- Error: tests/neg/i5525.scala:14:12 ----------------------------------------------------------------------------------
46+
14 | implicit case C4() // error: only access modifiers allowed
47+
| ^^^^
48+
| Only access modifiers are allowed on enum cases
49+
-- Error: tests/neg/i5525.scala:15:12 ----------------------------------------------------------------------------------
50+
15 | lazy case C5() // error: only access modifiers allowed
51+
| ^^^^
52+
| Only access modifiers are allowed on enum cases
53+
-- Error: tests/neg/i5525.scala:16:12 ----------------------------------------------------------------------------------
54+
16 | override case C7() // error: only access modifiers allowed
55+
| ^^^^
56+
| Only access modifiers are allowed on enum cases
57+
-- Error: tests/neg/i5525.scala:22:12 ----------------------------------------------------------------------------------
58+
22 | abstract case C1 // error: only access modifiers allowed
59+
| ^^^^
60+
| Only access modifiers are allowed on enum cases
61+
-- Error: tests/neg/i5525.scala:23:12 ----------------------------------------------------------------------------------
62+
23 | final case C2 // error: only access modifiers allowed
63+
| ^^^^
64+
| Only access modifiers are allowed on enum cases
65+
-- Error: tests/neg/i5525.scala:24:12 ----------------------------------------------------------------------------------
66+
24 | sealed case C3 // error: only access modifiers allowed
67+
| ^^^^
68+
| Only access modifiers are allowed on enum cases
69+
-- Error: tests/neg/i5525.scala:25:12 ----------------------------------------------------------------------------------
70+
25 | implicit case C4 // error: only access modifiers allowed
71+
| ^^^^
72+
| Only access modifiers are allowed on enum cases
73+
-- Error: tests/neg/i5525.scala:26:12 ----------------------------------------------------------------------------------
74+
26 | lazy case C5 // error: only access modifiers allowed
75+
| ^^^^
76+
| Only access modifiers are allowed on enum cases
77+
-- Error: tests/neg/i5525.scala:27:12 ----------------------------------------------------------------------------------
78+
27 | override case C7 // error: only access modifiers allowed
79+
| ^^^^
80+
| Only access modifiers are allowed on enum cases
81+
-- Error: tests/neg/i5525.scala:33:12 ----------------------------------------------------------------------------------
82+
33 | inline case C10() // error: only access modifiers allowed
83+
| ^^^^
84+
| end of statement expected but 'case' found
85+
-- Error: tests/neg/i5525.scala:36:11 ----------------------------------------------------------------------------------
86+
36 |final enum Foo13 { // error: only access modifiers and `into` allowed
87+
| ^^^^^
88+
| Only access modifiers are allowed on enum definitions
89+
-- Error: tests/neg/i5525.scala:42:8 -----------------------------------------------------------------------------------
90+
42 | infix case C2 extends Foo14[Int, Int] // error // error
91+
| ^^^^
92+
| end of statement expected but 'case' found
93+
-- Error: tests/neg/i5525.scala:49:7 -----------------------------------------------------------------------------------
94+
49 | into case C1 // error
95+
| ^^^^
96+
| end of statement expected but 'case' found
97+
-- [E145] Syntax Error: tests/neg/i5525.scala:32:5 ---------------------------------------------------------------------
98+
32 |enum Foo12 { // error: Enumerations must contain at least one case
99+
| ^^^^^
100+
| Enumerations must contain at least one case
101+
|
102+
| longer explanation available when compiling with `-explain`
103+
-- [E006] Not Found Error: tests/neg/i5525.scala:42:2 ------------------------------------------------------------------
104+
42 | infix case C2 extends Foo14[Int, Int] // error // error
105+
| ^^^^^
106+
| Not found: infix
107+
|
108+
| longer explanation available when compiling with `-explain`
109+
-- [E129] Potential Issue Warning: tests/neg/i5525.scala:49:2 ----------------------------------------------------------
110+
49 | into case C1 // error
111+
| ^^^^
112+
| A pure expression does nothing in statement position
113+
|
114+
| longer explanation available when compiling with `-explain`

tests/neg/i5525.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,20 @@ enum Foo11 {
3131

3232
enum Foo12 { // error: Enumerations must contain at least one case
3333
inline case C10() // error: only access modifiers allowed
34+
}
35+
36+
final enum Foo13 { // error: only access modifiers and `into` allowed
37+
case C1
38+
}
39+
40+
infix enum Foo14[A, B]{ // OK
41+
case C1 extends Foo14[Int, Int]
42+
infix case C2 extends Foo14[Int, Int] // error // error
43+
}
44+
45+
import language.experimental.into
46+
47+
into enum Foo15 { // OK
48+
case C0
49+
into case C1 // error
3450
}

tests/pos/infix-enum.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
infix enum Foo[A, B]:
2+
case C1 extends Foo[Int, Int]
3+
4+
val x: Int Foo Int = Foo.C1
5+

0 commit comments

Comments
 (0)