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

ast, parser, cgen: fix closure with nested closure variable (#15542)

This commit is contained in:
yuyi 2022-08-26 18:37:10 +08:00 committed by GitHub
parent 3af12271fb
commit 02a47f42f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 1 deletions

View File

@ -644,6 +644,7 @@ pub:
is_arg bool // fn args should not be autofreed
is_auto_deref bool
is_inherited bool
has_inherited bool
pub mut:
expr Expr
typ Type

View File

@ -460,8 +460,19 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) {
g.write('__closure_create($fn_name, ($ctx_struct*) memdup_uncollectable(&($ctx_struct){')
g.indent++
for var in node.inherited_vars {
mut has_inherited := false
if obj := node.decl.scope.find(var.name) {
if obj is ast.Var {
if obj.has_inherited {
has_inherited = true
g.writeln('.$var.name = $c.closure_ctx->$var.name,')
}
}
}
if !has_inherited {
g.writeln('.$var.name = $var.name,')
}
}
g.indent--
g.write('}, sizeof($ctx_struct)))')

View File

@ -1042,6 +1042,7 @@ fn (mut p Parser) closure_vars() []ast.Param {
...(*var)
pos: var_pos
is_inherited: true
has_inherited: var.is_inherited
is_used: false
is_changed: false
is_mut: is_mut

View File

@ -0,0 +1,2 @@
Test1{}, Test(Test1{})
Test1{}, Test(Test1{})

View File

@ -0,0 +1,23 @@
module main
interface Test {
test(fn (Test))
}
struct Test1 {
}
fn (t Test1) test(f fn (Test)) {
f(Test(t))
}
fn main() {
t := Test1{}
t.test(fn [t] (t1 Test) {
println('$t, $t1')
t.test(fn [t] (t2 Test) {
println('$t, $t2')
})
})
}