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

checker: check generic closure fn declaration (#16069)

This commit is contained in:
yuyi 2022-10-14 15:24:10 +08:00 committed by GitHub
parent 3e4cfc7343
commit 39d2aa71df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 0 deletions

View File

@ -415,6 +415,7 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type {
} }
c.table.cur_fn = unsafe { &node.decl } c.table.cur_fn = unsafe { &node.decl }
c.inside_anon_fn = true c.inside_anon_fn = true
mut has_generic := false
for mut var in node.inherited_vars { for mut var in node.inherited_vars {
parent_var := node.decl.scope.parent.find_var(var.name) or { parent_var := node.decl.scope.parent.find_var(var.name) or {
panic('unexpected checker error: cannot find parent of inherited variable `$var.name`') panic('unexpected checker error: cannot find parent of inherited variable `$var.name`')
@ -424,9 +425,16 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type {
var.pos) var.pos)
} }
var.typ = parent_var.typ var.typ = parent_var.typ
if var.typ.has_flag(.generic) {
has_generic = true
}
} }
c.stmts(node.decl.stmts) c.stmts(node.decl.stmts)
c.fn_decl(mut node.decl) c.fn_decl(mut node.decl)
if has_generic && node.decl.generic_names.len == 0 {
c.error('generic closure fn must specify type parameter, e.g. fn [foo] <T>()',
node.decl.pos)
}
return node.typ return node.typ
} }

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/generic_closure_fn_decl_err.vv:5:2: error: generic closure fn must specify type parameter, e.g. fn [foo] <T>()
3 |
4 | pub fn (mut app App) register<T>(service T) {
5 | fn [service] () {
| ~~~~~~~~~~~~~~~~~
6 | println(service)
7 | }()

View File

@ -0,0 +1,16 @@
pub struct App {
}
pub fn (mut app App) register<T>(service T) {
fn [service] () {
println(service)
}()
}
pub struct Service {
}
fn main() {
mut app := App{}
app.register(Service{})
}