# HG changeset patch # User Bram Moolenaar # Date 1626726604 -7200 # Node ID e56c8dc1a53482582e17bfd70b525f9e1e92fb36 # Parent a1eb85c2e0a5af61f009683307614f177c81a670 patch 8.2.3187: Vim9: popup timer callback is not compiled Commit: https://github.com/vim/vim/commit/9bb0dad0d8283c86fddf5b950f4fbb6fb8f12741 Author: Bram Moolenaar Date: Mon Jul 19 22:19:29 2021 +0200 patch 8.2.3187: Vim9: popup timer callback is not compiled Problem: Vim9: popup timer callback is not compiled. Solution: Compile the callback when creating the timer. diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -383,8 +383,8 @@ popup_add_timeout(win_T *wp, int time) typval_T tv; vim_snprintf((char *)cbbuf, sizeof(cbbuf), - "{_ -> popup_close(%d)}", wp->w_id); - if (get_lambda_tv(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK) + "(_) => popup_close(%d)", wp->w_id); + if (get_lambda_tv_and_compile(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK) { wp->w_popup_timer = create_timer(time, 0); wp->w_popup_timer->tr_callback = get_callback(&tv); diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro --- a/src/proto/vim9compile.pro +++ b/src/proto/vim9compile.pro @@ -11,6 +11,7 @@ char_u *peek_next_line_from_context(cctx char_u *next_line_from_context(cctx_T *cctx, int skip_comment); char_u *to_name_end(char_u *arg, int use_namespace); char_u *to_name_const_end(char_u *arg); +int get_lambda_tv_and_compile(char_u **arg, typval_T *rettv, int types_optional, evalarg_T *evalarg); exprtype_T get_compare_type(char_u *p, int *len, int *type_is); void error_white_both(char_u *op, int len); void fill_exarg_from_cctx(exarg_T *eap, cctx_T *cctx); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3187, +/**/ 3186, /**/ 3185, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3671,6 +3671,47 @@ compile_lambda(char_u **arg, cctx_T *cct } /* + * Get a lambda and compile it. Uses Vim9 syntax. + */ + int +get_lambda_tv_and_compile( + char_u **arg, + typval_T *rettv, + int types_optional, + evalarg_T *evalarg) +{ + int r; + ufunc_T *ufunc; + int save_sc_version = current_sctx.sc_version; + + // Get the funcref in "rettv". + current_sctx.sc_version = SCRIPT_VERSION_VIM9; + r = get_lambda_tv(arg, rettv, types_optional, evalarg); + current_sctx.sc_version = save_sc_version; + if (r != OK) + return r; + + // "rettv" will now be a partial referencing the function. + ufunc = rettv->vval.v_partial->pt_func; + + // Compile it here to get the return type. The return type is optional, + // when it's missing use t_unknown. This is recognized in + // compile_return(). + if (ufunc->uf_ret_type == NULL || ufunc->uf_ret_type->tt_type == VAR_VOID) + ufunc->uf_ret_type = &t_unknown; + compile_def_function(ufunc, FALSE, CT_NONE, NULL); + + if (ufunc->uf_def_status == UF_COMPILED) + { + // The return type will now be known. + set_function_type(ufunc); + return OK; + } + clear_tv(rettv); + return FAIL; +} + +/* * parse a dict: {key: val, [key]: val} * "*arg" points to the '{'. * ppconst->pp_is_const is set if all item values are a constant.