1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: check for anonymous function param redefinitions (#17382)

This commit is contained in:
Felipe Pena 2023-02-23 11:34:42 -03:00 committed by GitHub
parent d3870a0c7e
commit 248e9538ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 11 deletions

View File

@ -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 | }

View File

@ -0,0 +1,4 @@
fn main() {
a := fn (a int, a int) {
}
}

View File

@ -707,12 +707,19 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
} else { } else {
[]ast.Param{} []ast.Param{}
} }
inherited_vars_name := inherited_vars.map(it.name)
_, generic_names := p.parse_generic_types() _, generic_names := p.parse_generic_types()
args, _, is_variadic := p.fn_args() args, _, is_variadic := p.fn_args()
for arg in args { for arg in args {
if arg.name.len == 0 && p.table.sym(arg.typ).kind != .placeholder { if arg.name.len == 0 && p.table.sym(arg.typ).kind != .placeholder {
p.error_with_pos('use `_` to name an unused parameter', arg.pos) 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()) is_stack_obj := !arg.typ.has_flag(.shared_f) && (arg.is_mut || arg.typ.is_ptr())
p.scope.register(ast.Var{ p.scope.register(ast.Var{
name: arg.name name: arg.name
@ -767,17 +774,6 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
typ := ast.new_type(idx) typ := ast.new_type(idx)
p.inside_defer = old_inside_defer p.inside_defer = old_inside_defer
// name := p.table.get_type_name(typ) // 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{ return ast.AnonFn{
decl: ast.FnDecl{ decl: ast.FnDecl{
name: name name: name