From a262f5c22403634f40c57ca3e366d27c38bd1046 Mon Sep 17 00:00:00 2001 From: Swastik Date: Tue, 23 Jul 2024 16:20:34 +0530 Subject: [PATCH] checker: check enum value before use --- vlib/v/checker/checker.v | 8 ++++++++ vlib/v/checker/tests/enum_value_used_before_decl_err.out | 6 ++++++ vlib/v/checker/tests/enum_value_used_before_decl_err.vv | 5 +++++ 3 files changed, 19 insertions(+) create mode 100644 vlib/v/checker/tests/enum_value_used_before_decl_err.out create mode 100644 vlib/v/checker/tests/enum_value_used_before_decl_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 605eb3d901a73a..303d79a6491e3b 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1932,6 +1932,14 @@ fn (mut c Checker) enum_decl(mut node ast.EnumDecl) { c.error('the type of an enum value must be an integer type, like i8, u8, int, u64 etc.', field.expr.pos) } + if mut field.expr.expr is ast.EnumVal { + if field.expr.expr.enum_name == node.name { + if field.expr.expr.val !in seen_enum_field_names { + c.error('`${field.expr.expr.enum_name}.${field.expr.expr.val}` should be declared before using it', + field.expr.pos) + } + } + } } else { if mut field.expr is ast.Ident { diff --git a/vlib/v/checker/tests/enum_value_used_before_decl_err.out b/vlib/v/checker/tests/enum_value_used_before_decl_err.out new file mode 100644 index 00000000000000..3b4fe2633b9546 --- /dev/null +++ b/vlib/v/checker/tests/enum_value_used_before_decl_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/enum_value_used_before_decl_err.vv:2:10: error: cannot use `TestEnum.a` as not defined or declared later + 1 | enum TestEnum { + 2 | chan = int(TestEnum.a) + | ~~~~~~~~~~~~~~~ + 3 | a = 0 + 4 | b = 1 diff --git a/vlib/v/checker/tests/enum_value_used_before_decl_err.vv b/vlib/v/checker/tests/enum_value_used_before_decl_err.vv new file mode 100644 index 00000000000000..b244debcf53d0c --- /dev/null +++ b/vlib/v/checker/tests/enum_value_used_before_decl_err.vv @@ -0,0 +1,5 @@ +enum TestEnum { + chan = int(TestEnum.a) + a = 0 + b = 1 +}