patch 9.0.0502: a closure in a nested loop in a :def function does not work
Problem: A closure in a nested loop in a :def function does not work.
Solution: Use an array of loopvars, one per loop level.
diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro
index 3cc3576..f509523 100644
--- a/src/proto/userfunc.pro
+++ b/src/proto/userfunc.pro
@@ -16,7 +16,7 @@
int func_requires_g_prefix(ufunc_T *ufunc);
int func_name_refcount(char_u *name);
void func_clear_free(ufunc_T *fp, int force);
-int copy_lambda_to_global_func(char_u *lambda, char_u *global, short loop_var_idx, short loop_var_count, ectx_T *ectx);
+int copy_lambda_to_global_func(char_u *lambda, char_u *global, loopvarinfo_T *loopvarinfo, ectx_T *ectx);
int funcdepth_increment(void);
void funcdepth_decrement(void);
int funcdepth_get(void);
diff --git a/src/proto/vim9cmds.pro b/src/proto/vim9cmds.pro
index a0c3ade..4d9e983 100644
--- a/src/proto/vim9cmds.pro
+++ b/src/proto/vim9cmds.pro
@@ -11,8 +11,8 @@
char_u *compile_endfor(char_u *arg, cctx_T *cctx);
char_u *compile_while(char_u *arg, cctx_T *cctx);
char_u *compile_endwhile(char_u *arg, cctx_T *cctx);
-short get_loop_var_info(cctx_T *cctx, short *loop_var_idx);
-int get_loop_var_idx(cctx_T *cctx);
+int get_loop_var_info(cctx_T *cctx, loopvarinfo_T *lvi);
+void get_loop_var_idx(cctx_T *cctx, int idx, lvar_T *lvar);
char_u *compile_continue(char_u *arg, cctx_T *cctx);
char_u *compile_break(char_u *arg, cctx_T *cctx);
char_u *compile_block(char_u *arg, cctx_T *cctx);
diff --git a/src/proto/vim9execute.pro b/src/proto/vim9execute.pro
index 708f69a..f8e8106 100644
--- a/src/proto/vim9execute.pro
+++ b/src/proto/vim9execute.pro
@@ -9,11 +9,11 @@
int add_defer_function(char_u *name, int argcount, typval_T *argvars);
char_u *char_from_string(char_u *str, varnumber_T index);
char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive);
-int fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, short loop_var_idx, short loop_var_count, ectx_T *ectx);
+int fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, loopvarinfo_T *loopvarinfo, ectx_T *ectx);
int may_load_script(int sid, int *loaded);
typval_T *lookup_debug_var(char_u *name);
int may_break_in_function(ufunc_T *ufunc);
-void loopvars_check_refcount(loopvars_T *loopvars);
+int loopvars_check_refcount(loopvars_T *loopvars);
int set_ref_in_loopvars(int copyID);
int exe_typval_instr(typval_T *tv, typval_T *rettv);
char_u *exe_substitute_instr(void);
diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro
index 8fd3861..f0298f9 100644
--- a/src/proto/vim9instr.pro
+++ b/src/proto/vim9instr.pro
@@ -31,7 +31,7 @@
int generate_STORE(cctx_T *cctx, isntype_T isn_type, int idx, char_u *name);
int generate_STORENR(cctx_T *cctx, int idx, varnumber_T value);
int generate_LOAD(cctx_T *cctx, isntype_T isn_type, int idx, char_u *name, type_T *type);
-int generate_LOADOUTER(cctx_T *cctx, int idx, int nesting, int loop_idx, type_T *type);
+int generate_LOADOUTER(cctx_T *cctx, int idx, int nesting, int loop_depth, int loop_idx, type_T *type);
int generate_LOADV(cctx_T *cctx, char_u *name);
int generate_UNLET(cctx_T *cctx, isntype_T isn_type, char_u *name, int forceit);
int generate_LOCKCONST(cctx_T *cctx);
@@ -40,13 +40,13 @@
int generate_NEWLIST(cctx_T *cctx, int count, int use_null);
int generate_NEWDICT(cctx_T *cctx, int count, int use_null);
int generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc, isn_T **isnp);
-int generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name, short loop_var_idx, short loop_var_count);
+int generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name);
int generate_DEF(cctx_T *cctx, char_u *name, size_t len);
int generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where);
int generate_WHILE(cctx_T *cctx, int funcref_idx);
int generate_JUMP_IF_ARG_SET(cctx_T *cctx, int arg_off);
int generate_FOR(cctx_T *cctx, int loop_idx);
-int generate_ENDLOOP(cctx_T *cctx, int funcref_idx, int prev_local_count);
+int generate_ENDLOOP(cctx_T *cctx, loop_info_T *loop_info);
int generate_TRYCONT(cctx_T *cctx, int levels, int where);
int check_internal_func_args(cctx_T *cctx, int func_idx, int argcount, int method_call, type2_T **argtypes, type2_T *shuffled_argtypes);
int generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call);