To: vim_dev@googlegroups.com Subject: Patch 8.2.2770 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2770 Problem: Vim9: type of loop variable is not used. Solution: Parse and check the variable type. (closes #8107) Files: src/vim9compile.c, src/testdir/test_vim9_script.vim *** ../vim-8.2.2769/src/vim9compile.c 2021-04-15 13:42:15.914633807 +0200 --- src/vim9compile.c 2021-04-15 21:46:06.435912128 +0200 *************** *** 7514,7525 **** return NULL; } ! if (vartype->tt_type == VAR_LIST && vartype->tt_member->tt_type != VAR_ANY) { if (var_count == 1) item_type = vartype->tt_member; else if (vartype->tt_member->tt_type == VAR_LIST && vartype->tt_member->tt_member->tt_type != VAR_ANY) item_type = vartype->tt_member->tt_member; } --- 7514,7529 ---- return NULL; } ! if (vartype->tt_type == VAR_STRING) ! item_type = &t_string; ! else if (vartype->tt_type == VAR_LIST ! && vartype->tt_member->tt_type != VAR_ANY) { if (var_count == 1) item_type = vartype->tt_member; else if (vartype->tt_member->tt_type == VAR_LIST && vartype->tt_member->tt_member->tt_type != VAR_ANY) + // TODO: should get the type from item_type = vartype->tt_member->tt_member; } *************** *** 7557,7568 **** --- 7561,7579 ---- int opt_flags = 0; int vimvaridx = -1; type_T *type = &t_any; + type_T *lhs_type = &t_any; + where_T where; p = skip_var_one(arg, FALSE); varlen = p - arg; name = vim_strnsave(arg, varlen); if (name == NULL) goto failed; + if (*p == ':') + { + p = skipwhite(p + 1); + lhs_type = parse_type(&p, cctx->ctx_type_list, TRUE); + } // TODO: script var not supported? if (get_var_dest(name, &dest, CMD_for, &opt_flags, *************** *** 7589,7596 **** } // Reserve a variable to store "var". ! // TODO: check for type ! var_lvar = reserve_local(cctx, arg, varlen, TRUE, &t_any); if (var_lvar == NULL) // out of memory or used as an argument goto failed; --- 7600,7614 ---- } // Reserve a variable to store "var". ! where.wt_index = var_count > 1 ? idx + 1 : 0; ! where.wt_variable = TRUE; ! if (lhs_type == &t_any) ! lhs_type = item_type; ! else if (item_type != &t_unknown ! && !(var_count > 1 && item_type == &t_any) ! && check_type(lhs_type, item_type, TRUE, where) == FAIL) ! goto failed; ! var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type); if (var_lvar == NULL) // out of memory or used as an argument goto failed; *************** *** 7602,7609 **** generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL); } - if (*p == ':') - p = skip_type(skipwhite(p + 1), FALSE); if (*p == ',' || *p == ';') ++p; arg = skipwhite(p); --- 7620,7625 ---- *** ../vim-8.2.2769/src/testdir/test_vim9_script.vim 2021-04-14 13:30:42.974156744 +0200 --- src/testdir/test_vim9_script.vim 2021-04-15 21:48:04.999300447 +0200 *************** *** 2343,2348 **** --- 2343,2354 ---- endfor assert_equal(6, total) + var chars = '' + for s: string in 'foobar' + chars ..= s + endfor + assert_equal('foobar', chars) + # unpack with type var res = '' for [n: number, s: string] in [[1, 'a'], [2, 'b']] *************** *** 2408,2413 **** --- 2414,2425 ---- endfor END CheckDefAndScriptFailure2(lines, 'E1018:', 'E46:', 3) + + lines =<< trim END + for nr: number in ['foo'] + endfor + END + CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got string', 1) enddef def Test_for_loop_script_var() *** ../vim-8.2.2769/src/version.c 2021-04-15 14:29:13.845189149 +0200 --- src/version.c 2021-04-15 21:47:06.019599335 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2770, /**/ -- To be rich is not the end, but only a change of worries. /// 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 ///