From 248e9538ca79ed3a6d9033b84d2132cf5f8a011e Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 23 Feb 2023 11:34:42 -0300 Subject: [PATCH] parser: check for anonymous function param redefinitions (#17382) --- .../tests/anon_arg_redefinition_err.out | 6 ++++++ .../checker/tests/anon_arg_redefinition_err.vv | 4 ++++ vlib/v/parser/fn.v | 18 +++++++----------- 3 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 vlib/v/checker/tests/anon_arg_redefinition_err.out create mode 100644 vlib/v/checker/tests/anon_arg_redefinition_err.vv diff --git a/vlib/v/checker/tests/anon_arg_redefinition_err.out b/vlib/v/checker/tests/anon_arg_redefinition_err.out new file mode 100644 index 0000000000..b8d94af4cc --- /dev/null +++ b/vlib/v/checker/tests/anon_arg_redefinition_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/anon_arg_redefinition_err.vv:2:18: error: redefinition of parameter `a` + 1 | fn main() { + 2 | a := fn (a int, a int) { + | ^ + 3 | } + 4 | } diff --git a/vlib/v/checker/tests/anon_arg_redefinition_err.vv b/vlib/v/checker/tests/anon_arg_redefinition_err.vv new file mode 100644 index 0000000000..83fac8e396 --- /dev/null +++ b/vlib/v/checker/tests/anon_arg_redefinition_err.vv @@ -0,0 +1,4 @@ +fn main() { + a := fn (a int, a int) { + } +} \ No newline at end of file diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 2f86e393b4..af120a589b 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -707,12 +707,19 @@ fn (mut p Parser) anon_fn() ast.AnonFn { } else { []ast.Param{} } + inherited_vars_name := inherited_vars.map(it.name) _, generic_names := p.parse_generic_types() args, _, is_variadic := p.fn_args() for arg in args { if arg.name.len == 0 && p.table.sym(arg.typ).kind != .placeholder { p.error_with_pos('use `_` to name an unused parameter', arg.pos) } + if arg.name in inherited_vars_name { + p.error_with_pos('the parameter name `${arg.name}` conflicts with the captured value name', + arg.pos) + } else if p.scope.known_var(arg.name) { + p.error_with_pos('redefinition of parameter `${arg.name}`', arg.pos) + } is_stack_obj := !arg.typ.has_flag(.shared_f) && (arg.is_mut || arg.typ.is_ptr()) p.scope.register(ast.Var{ name: arg.name @@ -767,17 +774,6 @@ fn (mut p Parser) anon_fn() ast.AnonFn { typ := ast.new_type(idx) p.inside_defer = old_inside_defer // name := p.table.get_type_name(typ) - if inherited_vars.len > 0 && args.len > 0 { - for arg in args { - for var in inherited_vars { - if arg.name == var.name { - p.error_with_pos('the parameter name `${arg.name}` conflicts with the captured value name', - arg.pos) - break - } - } - } - } return ast.AnonFn{ decl: ast.FnDecl{ name: name