Skip to content

Commit

Permalink
checker: suggest using the @[_allow_multiple_values] attribute, whe…
Browse files Browse the repository at this point in the history
…n declaring enums that have duplicate values (#22224)
  • Loading branch information
Delta456 authored Sep 16, 2024
1 parent b1ffa4e commit 0fb95a8
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 0 deletions.
34 changes: 34 additions & 0 deletions doc/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -5632,6 +5632,40 @@ fn main() {
}
```
```v
// @[_allow_multiple_values] allows an enum to have multiple duplicate values.
// Use it carefully, only when you really need it.

@[_allow_multiple_values]
enum ButtonStyle {
primary = 1
secondary = 2
success = 3

blurple = 1
grey = 2
gray = 2
green = 3
}

fn main() {
assert int(ButtonStyle.primary) == 1
assert int(ButtonStyle.blurple) == 1

assert int(ButtonStyle.secondary) == 2
assert int(ButtonStyle.gray) == 2
assert int(ButtonStyle.grey) == 2

assert int(ButtonStyle.success) == 3
assert int(ButtonStyle.green) == 3

assert ButtonStyle.primary == ButtonStyle.blurple
assert ButtonStyle.secondary == ButtonStyle.grey
assert ButtonStyle.secondary == ButtonStyle.gray
assert ButtonStyle.success == ButtonStyle.green
}
```
Struct field deprecations:
```v oksyntax
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,7 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) {
field.pos)
} else if !c.pref.translated && !c.file.is_translated && !node.is_multi_allowed
&& ilast + 1 in iseen {
c.add_error_detail('use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed')
c.error('enum value `${ilast + 1}` already exists', field.pos)
}
iseen << ilast + 1
Expand All @@ -1989,6 +1990,7 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) {
field.pos)
} else if !c.pref.translated && !c.file.is_translated && !node.is_multi_allowed
&& ulast + 1 in useen {
c.add_error_detail('use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed')
c.error('enum value `${ulast + 1}` already exists', field.pos)
}
useen << ulast + 1
Expand Down Expand Up @@ -2038,6 +2040,7 @@ fn (mut c Checker) check_enum_field_integer_literal(expr ast.IntegerLiteral, is_
}
if !overflows && !c.pref.translated && !c.file.is_translated && !is_multi_allowed {
if (is_signed && ival in iseen) || (!is_signed && uval in useen) {
c.add_error_detail('use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed')
c.error('enum value `${expr.val}` already exists', pos)
}
}
Expand Down
2 changes: 2 additions & 0 deletions vlib/v/checker/tests/enum_field_value_duplicate_a.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ vlib/v/checker/tests/enum_field_value_duplicate_a.vv:3:10: error: enum value `0`
| ^
4 | blue = 1
5 | alpha = 1
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_a.vv:5:10: error: enum value `1` already exists
3 | green = 0
4 | blue = 1
5 | alpha = 1
| ^
6 | }
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed
1 change: 1 addition & 0 deletions vlib/v/checker/tests/enum_field_value_duplicate_b.out
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_b.vv:4:2: error: enum value `0`
4 | blue // -1 + 1 = 0
| ~~~~
5 | }
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed
1 change: 1 addition & 0 deletions vlib/v/checker/tests/enum_field_value_duplicate_c.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_c.vv:6:12: error: enum value `1`
| ~~~~~~~~
7 | all = 0xFFFFFFFF
8 | }
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed
1 change: 1 addition & 0 deletions vlib/v/checker/tests/enum_field_value_duplicate_d.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_d.vv:6:6: error: enum value `1`
| ~~~
7 | }
8 |
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed
1 change: 1 addition & 0 deletions vlib/v/checker/tests/enum_field_value_duplicate_e.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ vlib/v/checker/tests/enum_field_value_duplicate_e.vv:4:6: error: enum value `2`
| ~~~
5 | }
6 |
Details: use `@[_allow_multiple_values]` attribute to allow multiple enum values. Use only when it is needed

0 comments on commit 0fb95a8

Please sign in to comment.