Skip to content

Commit 0fb95a8

Browse files
authored
checker: suggest using the @[_allow_multiple_values] attribute, when declaring enums that have duplicate values (#22224)
1 parent b1ffa4e commit 0fb95a8

7 files changed

+43
-0
lines changed

doc/docs.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5632,6 +5632,40 @@ fn main() {
56325632
}
56335633
```
56345634
5635+
```v
5636+
// @[_allow_multiple_values] allows an enum to have multiple duplicate values.
5637+
// Use it carefully, only when you really need it.
5638+
5639+
@[_allow_multiple_values]
5640+
enum ButtonStyle {
5641+
primary = 1
5642+
secondary = 2
5643+
success = 3
5644+
5645+
blurple = 1
5646+
grey = 2
5647+
gray = 2
5648+
green = 3
5649+
}
5650+
5651+
fn main() {
5652+
assert int(ButtonStyle.primary) == 1
5653+
assert int(ButtonStyle.blurple) == 1
5654+
5655+
assert int(ButtonStyle.secondary) == 2
5656+
assert int(ButtonStyle.gray) == 2
5657+
assert int(ButtonStyle.grey) == 2
5658+
5659+
assert int(ButtonStyle.success) == 3
5660+
assert int(ButtonStyle.green) == 3
5661+
5662+
assert ButtonStyle.primary == ButtonStyle.blurple
5663+
assert ButtonStyle.secondary == ButtonStyle.grey
5664+
assert ButtonStyle.secondary == ButtonStyle.gray
5665+
assert ButtonStyle.success == ButtonStyle.green
5666+
}
5667+
```
5668+
56355669
Struct field deprecations:
56365670
56375671
```v oksyntax

vlib/v/checker/checker.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,6 +1975,7 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) {
19751975
field.pos)
19761976
} else if !c.pref.translated && !c.file.is_translated && !node.is_multi_allowed
19771977
&& ilast + 1 in iseen {
1978+
c.add_error_detail('use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed')
19781979
c.error('enum value `${ilast + 1}` already exists', field.pos)
19791980
}
19801981
iseen << ilast + 1
@@ -1989,6 +1990,7 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) {
19891990
field.pos)
19901991
} else if !c.pref.translated && !c.file.is_translated && !node.is_multi_allowed
19911992
&& ulast + 1 in useen {
1993+
c.add_error_detail('use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed')
19921994
c.error('enum value `${ulast + 1}` already exists', field.pos)
19931995
}
19941996
useen << ulast + 1
@@ -2038,6 +2040,7 @@ fn (mut c Checker) check_enum_field_integer_literal(expr ast.IntegerLiteral, is_
20382040
}
20392041
if !overflows && !c.pref.translated && !c.file.is_translated && !is_multi_allowed {
20402042
if (is_signed && ival in iseen) || (!is_signed && uval in useen) {
2043+
c.add_error_detail('use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed')
20412044
c.error('enum value `${expr.val}` already exists', pos)
20422045
}
20432046
}

vlib/v/checker/tests/enum_field_value_duplicate_a.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ vlib/v/checker/tests/enum_field_value_duplicate_a.vv:3:10: error: enum value `0`
55
| ^
66
4 | blue = 1
77
5 | alpha = 1
8+
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed
89
vlib/v/checker/tests/enum_field_value_duplicate_a.vv:5:10: error: enum value `1` already exists
910
3 | green = 0
1011
4 | blue = 1
1112
5 | alpha = 1
1213
| ^
1314
6 | }
15+
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed

vlib/v/checker/tests/enum_field_value_duplicate_b.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_b.vv:4:2: error: enum value `0`
44
4 | blue // -1 + 1 = 0
55
| ~~~~
66
5 | }
7+
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed

vlib/v/checker/tests/enum_field_value_duplicate_c.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_c.vv:6:12: error: enum value `1`
55
| ~~~~~~~~
66
7 | all = 0xFFFFFFFF
77
8 | }
8+
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed

vlib/v/checker/tests/enum_field_value_duplicate_d.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_d.vv:6:6: error: enum value `1`
55
| ~~~
66
7 | }
77
8 |
8+
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed

vlib/v/checker/tests/enum_field_value_duplicate_e.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_e.vv:4:6: error: enum value `2`
55
| ~~~
66
5 | }
77
6 |
8+
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed

0 commit comments

Comments
 (0)