i can't build after pulling this patch On Tue, Apr 13, 2021 at 1:54 PM Bram Moolenaar <b...@moolenaar.net> wrote:
> > Patch 8.2.2759 > Problem: Vim9: for loop infers type of loop variable. > Solution: Do not get the member type. (closes #8102) > Files: src/vim9type.c, src/proto/vim9type.pro, src/list.c, > src/vim9script.c, src/proto/vim9script.pro, src/vim.h, > src/testdir/test_vim9_script.vim > > > *** ../vim-8.2.2758/src/vim9type.c 2021-03-18 22:15:00.589208304 +0100 > --- src/vim9type.c 2021-04-13 20:37:54.449383083 +0200 > *************** > *** 252,260 **** > /* > * Get a type_T for a typval_T. > * "type_gap" is used to temporarily create types in. > */ > static type_T * > ! typval2type_int(typval_T *tv, int copyID, garray_T *type_gap) > { > type_T *type; > type_T *member_type = &t_any; > --- 252,261 ---- > /* > * Get a type_T for a typval_T. > * "type_gap" is used to temporarily create types in. > + * When "do_member" is TRUE also get the member type, otherwise use > "any". > */ > static type_T * > ! typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int > do_member) > { > type_T *type; > type_T *member_type = &t_any; > *************** > *** 274,279 **** > --- 275,282 ---- > > if (l == NULL || l->lv_first == NULL) > return &t_list_empty; > + if (!do_member) > + return &t_list_any; > if (l->lv_first == &range_list_item) > return &t_list_number; > if (l->lv_copyID == copyID) > *************** > *** 282,290 **** > l->lv_copyID = copyID; > > // Use the common type of all members. > ! member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap); > for (li = l->lv_first->li_next; li != NULL; li = li->li_next) > ! common_type(typval2type(&li->li_tv, copyID, type_gap), > member_type, &member_type, > type_gap); > return get_list_type(member_type, type_gap); > } > --- 285,293 ---- > l->lv_copyID = copyID; > > // Use the common type of all members. > ! member_type = typval2type(&l->lv_first->li_tv, copyID, type_gap, > TRUE); > for (li = l->lv_first->li_next; li != NULL; li = li->li_next) > ! common_type(typval2type(&li->li_tv, copyID, type_gap, TRUE), > member_type, &member_type, > type_gap); > return get_list_type(member_type, type_gap); > } > *************** > *** 297,302 **** > --- 300,307 ---- > > if (d == NULL || d->dv_hashtab.ht_used == 0) > return &t_dict_empty; > + if (!do_member) > + return &t_dict_any; > if (d->dv_copyID == copyID) > // avoid recursion > return &t_dict_any; > *************** > *** 305,313 **** > // Use the common type of all values. > dict_iterate_start(tv, &iter); > dict_iterate_next(&iter, &value); > ! member_type = typval2type(value, copyID, type_gap); > while (dict_iterate_next(&iter, &value) != NULL) > ! common_type(typval2type(value, copyID, type_gap), > member_type, &member_type, > type_gap); > return get_dict_type(member_type, type_gap); > } > --- 310,318 ---- > // Use the common type of all values. > dict_iterate_start(tv, &iter); > dict_iterate_next(&iter, &value); > ! member_type = typval2type(value, copyID, type_gap, TRUE); > while (dict_iterate_next(&iter, &value) != NULL) > ! common_type(typval2type(value, copyID, type_gap, TRUE), > member_type, &member_type, > type_gap); > return get_dict_type(member_type, type_gap); > } > *************** > *** 378,388 **** > /* > * Get a type_T for a typval_T. > * "type_list" is used to temporarily create types in. > */ > type_T * > ! typval2type(typval_T *tv, int copyID, garray_T *type_gap) > { > ! type_T *type = typval2type_int(tv, copyID, type_gap); > > if (type != NULL && type != &t_bool > && (tv->v_type == VAR_NUMBER > --- 383,394 ---- > /* > * Get a type_T for a typval_T. > * "type_list" is used to temporarily create types in. > + * When "do_member" is TRUE also get the member type, otherwise use > "any". > */ > type_T * > ! typval2type(typval_T *tv, int copyID, garray_T *type_gap, int do_member) > { > ! type_T *type = typval2type_int(tv, copyID, type_gap, do_member); > > if (type != NULL && type != &t_bool > && (tv->v_type == VAR_NUMBER > *************** > *** 404,410 **** > return &t_list_string; > if (tv->v_type == VAR_DICT) // e.g. for v:completed_item > return &t_dict_any; > ! return typval2type(tv, get_copyID(), type_gap); > } > > int > --- 410,416 ---- > return &t_list_string; > if (tv->v_type == VAR_DICT) // e.g. for v:completed_item > return &t_dict_any; > ! return typval2type(tv, get_copyID(), type_gap, TRUE); > } > > int > *************** > *** 429,435 **** > int res = FAIL; > > ga_init2(&type_list, sizeof(type_T *), 10); > ! actual_type = typval2type(actual_tv, get_copyID(), &type_list); > if (actual_type != NULL) > res = check_type(expected, actual_type, TRUE, where); > clear_type_list(&type_list); > --- 435,441 ---- > int res = FAIL; > > ga_init2(&type_list, sizeof(type_T *), 10); > ! actual_type = typval2type(actual_tv, get_copyID(), &type_list, TRUE); > if (actual_type != NULL) > res = check_type(expected, actual_type, TRUE, where); > clear_type_list(&type_list); > *************** > *** 1210,1216 **** > > rettv->v_type = VAR_STRING; > ga_init2(&type_list, sizeof(type_T *), 10); > ! type = typval2type(argvars, get_copyID(), &type_list); > name = type_name(type, &tofree); > if (tofree != NULL) > rettv->vval.v_string = (char_u *)tofree; > --- 1216,1222 ---- > > rettv->v_type = VAR_STRING; > ga_init2(&type_list, sizeof(type_T *), 10); > ! type = typval2type(argvars, get_copyID(), &type_list, TRUE); > name = type_name(type, &tofree); > if (tofree != NULL) > rettv->vval.v_string = (char_u *)tofree; > *** ../vim-8.2.2758/src/proto/vim9type.pro 2021-03-18 > 22:15:00.589208304 +0100 > --- src/proto/vim9type.pro 2021-04-13 20:35:14.809994522 +0200 > *************** > *** 9,15 **** > type_T *get_func_type(type_T *ret_type, int argcount, garray_T > *type_gap); > int func_type_add_arg_types(type_T *functype, int argcount, garray_T > *type_gap); > int need_convert_to_bool(type_T *type, typval_T *tv); > ! type_T *typval2type(typval_T *tv, int copyID, garray_T *type_gap); > type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap); > int check_typval_arg_type(type_T *expected, typval_T *actual_tv, int > arg_idx); > int check_typval_type(type_T *expected, typval_T *actual_tv, where_T > where); > --- 9,15 ---- > type_T *get_func_type(type_T *ret_type, int argcount, garray_T > *type_gap); > int func_type_add_arg_types(type_T *functype, int argcount, garray_T > *type_gap); > int need_convert_to_bool(type_T *type, typval_T *tv); > ! type_T *typval2type(typval_T *tv, int copyID, garray_T *type_gap, int > do_member); > type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap); > int check_typval_arg_type(type_T *expected, typval_T *actual_tv, int > arg_idx); > int check_typval_type(type_T *expected, typval_T *actual_tv, where_T > where); > *** ../vim-8.2.2758/src/list.c 2021-04-08 20:09:49.267143853 +0200 > --- src/list.c 2021-04-13 20:35:33.581920676 +0200 > *************** > *** 2059,2065 **** > { > // Check that map() does not change the type of the dict. > ga_init2(&type_list, sizeof(type_T *), 10); > ! type = typval2type(argvars, get_copyID(), &type_list); > } > > if (argvars[0].v_type == VAR_BLOB) > --- 2059,2065 ---- > { > // Check that map() does not change the type of the dict. > ga_init2(&type_list, sizeof(type_T *), 10); > ! type = typval2type(argvars, get_copyID(), &type_list, TRUE); > } > > if (argvars[0].v_type == VAR_BLOB) > *************** > *** 2565,2571 **** > { > // Check that map() does not change the type of the dict. > ga_init2(&type_list, sizeof(type_T *), 10); > ! type = typval2type(argvars, get_copyID(), &type_list); > } > > if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) > --- 2565,2571 ---- > { > // Check that map() does not change the type of the dict. > ga_init2(&type_list, sizeof(type_T *), 10); > ! type = typval2type(argvars, get_copyID(), &type_list, TRUE); > } > > if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) > *** ../vim-8.2.2758/src/vim9script.c 2021-04-01 13:17:46.356214572 +0200 > --- src/vim9script.c 2021-04-13 20:36:55.257605669 +0200 > *************** > *** 713,719 **** > * When "create" is TRUE this is a new variable, otherwise find and > update an > * existing variable. > * "flags" can have ASSIGN_FINAL or ASSIGN_CONST. > ! * When "*type" is NULL use "tv" for the type and update "*type". > */ > void > update_vim9_script_var( > --- 713,720 ---- > * When "create" is TRUE this is a new variable, otherwise find and > update an > * existing variable. > * "flags" can have ASSIGN_FINAL or ASSIGN_CONST. > ! * When "*type" is NULL use "tv" for the type and update "*type". If > ! * "do_member" is TRUE also use the member type, otherwise use "any". > */ > void > update_vim9_script_var( > *************** > *** 721,727 **** > dictitem_T *di, > int flags, > typval_T *tv, > ! type_T **type) > { > scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); > hashitem_T *hi; > --- 722,729 ---- > dictitem_T *di, > int flags, > typval_T *tv, > ! type_T **type, > ! int do_member) > { > scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); > hashitem_T *hi; > *************** > *** 774,780 **** > if (sv != NULL) > { > if (*type == NULL) > ! *type = typval2type(tv, get_copyID(), &si->sn_type_list); > sv->sv_type = *type; > } > > --- 776,783 ---- > if (sv != NULL) > { > if (*type == NULL) > ! *type = typval2type(tv, get_copyID(), &si->sn_type_list, > ! > do_member); > sv->sv_type = *type; > } > > *** ../vim-8.2.2758/src/proto/vim9script.pro 2021-03-31 > 21:07:21.312591129 +0200 > --- src/proto/vim9script.pro 2021-04-13 20:38:08.249331798 +0200 > *************** > *** 12,18 **** > int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, > cctx_T *cctx, int verbose); > char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, > evalarg_T *evalarg, void *cctx); > char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg); > ! void update_vim9_script_var(int create, dictitem_T *di, int flags, > typval_T *tv, type_T **type); > void hide_script_var(scriptitem_T *si, int idx, int func_defined); > void free_all_script_vars(scriptitem_T *si); > svar_T *find_typval_in_script(typval_T *dest); > --- 12,18 ---- > int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, > cctx_T *cctx, int verbose); > char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, > evalarg_T *evalarg, void *cctx); > char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg); > ! void update_vim9_script_var(int create, dictitem_T *di, int flags, > typval_T *tv, type_T **type, int do_member); > void hide_script_var(scriptitem_T *si, int idx, int func_defined); > void free_all_script_vars(scriptitem_T *si); > svar_T *find_typval_in_script(typval_T *dest); > *** ../vim-8.2.2758/src/vim.h 2021-04-10 22:35:40.487360271 +0200 > --- src/vim.h 2021-04-13 20:40:16.204866053 +0200 > *************** > *** 2157,2162 **** > --- 2157,2163 ---- > #define ASSIGN_NO_DECL 0x04 // "name = expr" without > ":let"/":const"/":final" > #define ASSIGN_DECL 0x08 // may declare variable if it does not exist > #define ASSIGN_UNPACK 0x10 // using [a, b] = list > + #define ASSIGN_NO_MEMBER_TYPE 0x20 // use "any" for list and dict member > type > > #include "ex_cmds.h" // Ex command defines > #include "spell.h" // spell checking stuff > *** ../vim-8.2.2758/src/testdir/test_vim9_script.vim 2021-04-10 > 20:52:39.991416717 +0200 > --- src/testdir/test_vim9_script.vim 2021-04-13 20:50:12.098849100 +0200 > *************** > *** 2295,2364 **** > enddef > > def Test_for_loop() > ! var result = '' > ! for cnt in range(7) > ! if cnt == 4 > ! break > ! endif > ! if cnt == 2 > ! continue > ! endif > ! result ..= cnt .. '_' > ! endfor > ! assert_equal('0_1_3_', result) > > ! var concat = '' > ! for str in eval('["one", "two"]') > ! concat ..= str > ! endfor > ! assert_equal('onetwo', concat) > > ! var total = 0 > ! for nr in > ! [1, 2, 3] > ! total += nr > ! endfor > ! assert_equal(6, total) > > ! total = 0 > ! for nr > ! in [1, 2, 3] > ! total += nr > ! endfor > ! assert_equal(6, total) > > ! total = 0 > ! for nr > ! in > ! [1, 2, 3] > ! total += nr > ! endfor > ! assert_equal(6, total) > > var res = "" > for [n: number, s: string] in [[1, 'a'], [2, 'b']] > res ..= n .. s > endfor > assert_equal('1a2b', res) > - > - # loop over string > - res = '' > - for c in 'aéc̀d' > - res ..= c .. '-' > - endfor > - assert_equal('a-é-c̀-d-', res) > - > - res = '' > - for c in '' > - res ..= c .. '-' > - endfor > - assert_equal('', res) > - > - res = '' > - for c in test_null_string() > - res ..= c .. '-' > - endfor > - assert_equal('', res) > enddef > > def Test_for_loop_fails() > --- 2295,2376 ---- > enddef > > def Test_for_loop() > ! var lines =<< trim END > ! var result = '' > ! for cnt in range(7) > ! if cnt == 4 > ! break > ! endif > ! if cnt == 2 > ! continue > ! endif > ! result ..= cnt .. '_' > ! endfor > ! assert_equal('0_1_3_', result) > > ! var concat = '' > ! for str in eval('["one", "two"]') > ! concat ..= str > ! endfor > ! assert_equal('onetwo', concat) > > ! var total = 0 > ! for nr in > ! [1, 2, 3] > ! total += nr > ! endfor > ! assert_equal(6, total) > > ! total = 0 > ! for nr > ! in [1, 2, 3] > ! total += nr > ! endfor > ! assert_equal(6, total) > > ! total = 0 > ! for nr > ! in > ! [1, 2, 3] > ! total += nr > ! endfor > ! assert_equal(6, total) > ! > ! # loop over string > ! var res = '' > ! for c in 'aéc̀d' > ! res ..= c .. '-' > ! endfor > ! assert_equal('a-é-c̀-d-', res) > ! > ! res = '' > ! for c in '' > ! res ..= c .. '-' > ! endfor > ! assert_equal('', res) > ! > ! res = '' > ! for c in test_null_string() > ! res ..= c .. '-' > ! endfor > ! assert_equal('', res) > ! > ! var foo: list<dict<any>> = [ > ! {a: 'Cat'} > ! ] > ! for dd in foo > ! dd.counter = 12 > ! endfor > ! assert_equal([{a: 'Cat', counter: 12}], foo) > ! END > ! CheckDefAndScriptSuccess(lines) > > + # TODO: should also work at script level > var res = "" > for [n: number, s: string] in [[1, 'a'], [2, 'b']] > res ..= n .. s > endfor > assert_equal('1a2b', res) > enddef > > def Test_for_loop_fails() > *************** > *** 2471,2490 **** > enddef > > def Test_for_loop_with_try_continue() > ! var looped = 0 > ! var cleanup = 0 > ! for i in range(3) > ! looped += 1 > ! try > ! eval [][0] > ! catch > ! continue > ! finally > ! cleanup += 1 > ! endtry > ! endfor > ! assert_equal(3, looped) > ! assert_equal(3, cleanup) > enddef > > def Test_while_loop() > --- 2483,2505 ---- > enddef > > def Test_for_loop_with_try_continue() > ! var lines =<< trim END > ! var looped = 0 > ! var cleanup = 0 > ! for i in range(3) > ! looped += 1 > ! try > ! eval [][0] > ! catch > ! continue > ! finally > ! cleanup += 1 > ! endtry > ! endfor > ! assert_equal(3, looped) > ! assert_equal(3, cleanup) > ! END > ! CheckDefAndScriptSuccess(lines) > enddef > > def Test_while_loop() > *** ../vim-8.2.2758/src/version.c 2021-04-12 22:02:32.308393464 +0200 > --- src/version.c 2021-04-13 20:52:40.854365290 +0200 > *************** > *** 752,753 **** > --- 752,755 ---- > { /* Add new patch number below this line */ > + /**/ > + 2759, > /**/ > > -- > From "know your smileys": > [:-) Frankenstein's monster > > /// Bram Moolenaar -- b...@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 > /// > > -- > -- > You received this message from the "vim_dev" maillist. > Do not top-post! Type your reply below the text you are replying to. > For more information, visit http://www.vim.org/maillist.php > > --- > You received this message because you are subscribed to the Google Groups > "vim_dev" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to vim_dev+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/vim_dev/202104131854.13DIsph21051991%40masaka.moolenaar.net > . > -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/vim_dev/CALfSX1wmz5Bzm0hagJ0RT-E3HwAeCW9CtgD0apeR%3D%2BkBYjXiGQ%40mail.gmail.com.