From 3126ae305c9a95f982c29ebd8ae7da6b703267b0 Mon Sep 17 00:00:00 2001 From: Enzo Date: Fri, 18 Sep 2020 23:47:50 +0200 Subject: [PATCH] checker: verify use of blank identifier (#6412) --- vlib/v/checker/checker.v | 42 +++++++++---------- .../checker/tests/blank_ident_invalid_use.out | 5 +++ .../checker/tests/blank_ident_invalid_use.vv | 3 ++ 3 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 vlib/v/checker/tests/blank_ident_invalid_use.out create mode 100644 vlib/v/checker/tests/blank_ident_invalid_use.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 199700dbd..441a5f473 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2718,6 +2718,9 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { c.const_deps << name } if ident.kind == .blank_ident { + if ident.tok_kind !in [.assign, .decl_assign] { + c.error('undefined ident: `_` (may only be used in assignments)', ident.pos) + } return table.void_type } // second use @@ -2828,29 +2831,26 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { if ident.language == .c { return table.int_type } - if ident.name != '_' { - if c.inside_sql { - if field := c.table.struct_find_field(c.cur_orm_ts, ident.name) { - return field.typ - } - } - if ident.kind == .unresolved && ident.mod != 'builtin' { - // search in the `builtin` idents, for example - // main.compare_f32 may actually be builtin.compare_f32 - saved_mod := ident.mod - ident.mod = 'builtin' - builtin_type := c.ident(ident) - if builtin_type != table.void_type { - return builtin_type - } - ident.mod = saved_mod + if c.inside_sql { + if field := c.table.struct_find_field(c.cur_orm_ts, ident.name) { + return field.typ } - if ident.tok_kind == .assign { - c.error('undefined ident: `$ident.name` (use `:=` to declare a variable)', - ident.pos) - } else { - c.error('undefined ident: `$ident.name`', ident.pos) + } + if ident.kind == .unresolved && ident.mod != 'builtin' { + // search in the `builtin` idents, for example + // main.compare_f32 may actually be builtin.compare_f32 + saved_mod := ident.mod + ident.mod = 'builtin' + builtin_type := c.ident(ident) + if builtin_type != table.void_type { + return builtin_type } + ident.mod = saved_mod + } + if ident.tok_kind == .assign { + c.error('undefined ident: `$ident.name` (use `:=` to declare a variable)', ident.pos) + } else { + c.error('undefined ident: `$ident.name`', ident.pos) } if c.table.known_type(ident.name) { // e.g. `User` in `json.decode(User, '...')` diff --git a/vlib/v/checker/tests/blank_ident_invalid_use.out b/vlib/v/checker/tests/blank_ident_invalid_use.out new file mode 100644 index 000000000..9385664f5 --- /dev/null +++ b/vlib/v/checker/tests/blank_ident_invalid_use.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/blank_ident_invalid_use.vv:2:8: error: undefined ident: `_` (may only be used in assignments) + 1 | fn main() { + 2 | _ := [_] + | ^ + 3 | } diff --git a/vlib/v/checker/tests/blank_ident_invalid_use.vv b/vlib/v/checker/tests/blank_ident_invalid_use.vv new file mode 100644 index 000000000..4be90be1b --- /dev/null +++ b/vlib/v/checker/tests/blank_ident_invalid_use.vv @@ -0,0 +1,3 @@ +fn main() { + _ := [_] +} -- 2.39.5