To: vim_dev@googlegroups.com Subject: Patch 9.0.1203 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1203 Problem: Return type of values() is always list. Solution: Use the member type if possible. (issue #11822) Files: src/vim9instr.c, src/evalfunc.c, src/proto/evalfunc.pro, src/vim9type.c, src/testdir/test_vim9_builtin.vim *** ../vim-9.0.1202/src/vim9instr.c 2023-01-03 12:33:23.082974364 +0000 --- src/vim9instr.c 2023-01-15 17:41:24.290164547 +0000 *************** *** 1619,1625 **** // Drop the argument types and push the return type. stack->ga_len -= argcount; ! type = internal_func_ret_type(func_idx, argcount, argtypes, &decl_type); if (push_type_stack2(cctx, type, decl_type) == FAIL) return FAIL; --- 1619,1626 ---- // Drop the argument types and push the return type. stack->ga_len -= argcount; ! type = internal_func_ret_type(func_idx, argcount, argtypes, &decl_type, ! cctx->ctx_type_list); if (push_type_stack2(cctx, type, decl_type) == FAIL) return FAIL; *** ../vim-9.0.1202/src/evalfunc.c 2023-01-09 19:04:19.300528373 +0000 --- src/evalfunc.c 2023-01-15 17:49:05.441793716 +0000 *************** *** 1136,1141 **** --- 1136,1143 ---- static argcheck_T arg23_writefile[] = {arg_list_or_blob, arg_string, arg_string}; static argcheck_T arg24_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number}; + // Can be used by functions called through "f_retfunc" to create new types. + static garray_T *current_type_gap = NULL; /* * Functions that return the return type of a builtin function. *************** *** 1438,1443 **** --- 1440,1468 ---- // Depending on the count would be a string or a list of strings. return &t_any; } + // for values(): list of member of first argument + static type_T * + ret_list_member(int argcount, + type2_T *argtypes, + type_T **decl_type) + { + if (argcount > 0) + { + type_T *t = argtypes[0].type_decl; + if (current_type_gap != NULL + && (t->tt_type == VAR_DICT || t->tt_type == VAR_LIST)) + t = get_list_type(t->tt_member, current_type_gap); + else + t = &t_list_any; + *decl_type = t; + + t = argtypes[0].type_curr; + if (current_type_gap != NULL + && (t->tt_type == VAR_DICT || t->tt_type == VAR_LIST)) + return get_list_type(t->tt_member, current_type_gap); + } + return &t_list_any; + } /* * Used for getqflist(): returns list if there is no argument, dict if there is *************** *** 2759,2765 **** {"uniq", 1, 3, FEARG_1, arg13_sortuniq, ret_first_arg, f_uniq}, {"values", 1, 1, FEARG_1, arg1_dict_any, ! ret_list_any, f_values}, {"virtcol", 1, 2, FEARG_1, arg2_string_or_list_bool, ret_virtcol, f_virtcol}, {"virtcol2col", 3, 3, FEARG_1, arg3_number, --- 2784,2790 ---- {"uniq", 1, 3, FEARG_1, arg13_sortuniq, ret_first_arg, f_uniq}, {"values", 1, 1, FEARG_1, arg1_dict_any, ! ret_list_member, f_values}, {"virtcol", 1, 2, FEARG_1, arg2_string_or_list_bool, ret_virtcol, f_virtcol}, {"virtcol2col", 3, 3, FEARG_1, arg3_number, *************** *** 2993,3006 **** int idx, int argcount, type2_T *argtypes, ! type_T **decl_type) { type_T *ret; *decl_type = NULL; ret = global_functions[idx].f_retfunc(argcount, argtypes, decl_type); if (*decl_type == NULL) *decl_type = ret; return ret; } --- 3018,3034 ---- int idx, int argcount, type2_T *argtypes, ! type_T **decl_type, ! garray_T *type_gap) { type_T *ret; + current_type_gap = type_gap; *decl_type = NULL; ret = global_functions[idx].f_retfunc(argcount, argtypes, decl_type); if (*decl_type == NULL) *decl_type = ret; + current_type_gap = NULL; return ret; } *** ../vim-9.0.1202/src/proto/evalfunc.pro 2022-09-29 19:14:37.675876694 +0100 --- src/proto/evalfunc.pro 2023-01-15 17:48:24.881817415 +0000 *************** *** 7,13 **** char *internal_func_name(int idx); int internal_func_check_arg_types(type2_T *types, int idx, int argcount, cctx_T *cctx); void internal_func_get_argcount(int idx, int *argcount, int *min_argcount); ! type_T *internal_func_ret_type(int idx, int argcount, type2_T *argtypes, type_T **decl_type); int internal_func_is_map(int idx); int check_internal_func(int idx, int argcount); int call_internal_func(char_u *name, int argcount, typval_T *argvars, typval_T *rettv); --- 7,13 ---- char *internal_func_name(int idx); int internal_func_check_arg_types(type2_T *types, int idx, int argcount, cctx_T *cctx); void internal_func_get_argcount(int idx, int *argcount, int *min_argcount); ! type_T *internal_func_ret_type(int idx, int argcount, type2_T *argtypes, type_T **decl_type, garray_T *type_gap); int internal_func_is_map(int idx); int check_internal_func(int idx, int argcount); int call_internal_func(char_u *name, int argcount, typval_T *argvars, typval_T *rettv); *** ../vim-9.0.1202/src/vim9type.c 2023-01-15 16:54:53.746480577 +0000 --- src/vim9type.c 2023-01-15 17:42:48.662076095 +0000 *************** *** 539,545 **** type_T *decl_type; // unused internal_func_get_argcount(idx, &argcount, &min_argcount); ! member_type = internal_func_ret_type(idx, 0, NULL, &decl_type); } else ufunc = find_func(name, FALSE); --- 539,546 ---- type_T *decl_type; // unused internal_func_get_argcount(idx, &argcount, &min_argcount); ! member_type = internal_func_ret_type(idx, 0, NULL, &decl_type, ! type_gap); } else ufunc = find_func(name, FALSE); *** ../vim-9.0.1202/src/testdir/test_vim9_builtin.vim 2022-12-02 21:37:36.400878227 +0000 --- src/testdir/test_vim9_builtin.vim 2023-01-15 17:53:59.613652836 +0000 *************** *** 4740,4745 **** --- 4740,4770 ---- v9.CheckDefAndScriptFailure(['values([])'], ['E1013: Argument 1: type mismatch, expected dict but got list', 'E1206: Dictionary required for argument 1']) assert_equal([], {}->values()) assert_equal(['sun'], {star: 'sun'}->values()) + + # the return type of values() is list + var lines =<< trim END + vim9script + + class Foo + this.val: number + def Add() + echo this.val + enddef + endclass + + def Process(FooDict: dict) + for foo in values(FooDict) + foo.Add() + endfor + enddef + + disas Process + + var D = {'x': Foo.new(22)} + + Process(D) + END + v9.CheckScriptSuccess(lines) enddef def Test_virtcol() *** ../vim-9.0.1202/src/version.c 2023-01-15 16:54:53.746480577 +0000 --- src/version.c 2023-01-15 17:54:20.581644445 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1203, /**/ -- hundred-and-one symptoms of being an internet addict: 18. Your wife drapes a blond wig over your monitor to remind you of what she looks like. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///