Patch 8.2.3869
Problem: Vim9: type checking for "any" is inconsistent.
Solution: Always use a runtime type check for using "any" for a more
specific type.
Files: src/vim9type.c, src/vim9compile.c, src/vim9expr.c,
src/testdir/test_vim9_func.vim
*** ../vim-8.2.3868/src/vim9type.c 2021-12-21 13:30:38.732749872 +0000
--- src/vim9type.c 2021-12-22 13:08:44.653775876 +0000
***************
*** 477,483 ****
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);
return res;
}
--- 477,495 ----
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_maybe(expected, actual_type, TRUE, where);
! if (res == MAYBE && !(actual_type->tt_type == VAR_FUNC
! && actual_type->tt_member == &t_unknown))
! {
! // If a type check is needed that means assigning "any" or
! // "unknown" to a more specific type, which fails here.
! // Execpt when it looks like a lambda, since they have an
! // incomplete type.
! type_mismatch_where(expected, actual_type, where);
! res = FAIL;
! }
! }
clear_type_list(&type_list);
return res;
}
***************
*** 567,575 ****
{
// tt_type should match, except that a "partial" can be assigned to a
// variable with type "func".
! // And "unknown" (using global variable) needs a runtime type check.
if (!(expected->tt_type == actual->tt_type
|| actual->tt_type == VAR_UNKNOWN
|| (expected->tt_type == VAR_FUNC
&& actual->tt_type == VAR_PARTIAL)))
{
--- 579,589 ----
{
// tt_type should match, except that a "partial" can be assigned to a
// variable with type "func".
! // And "unknown" (using global variable) and "any" need a runtime type
! // check.
if (!(expected->tt_type == actual->tt_type
|| actual->tt_type == VAR_UNKNOWN
+ || actual->tt_type == VAR_ANY
|| (expected->tt_type == VAR_FUNC
&& actual->tt_type == VAR_PARTIAL)))
{
***************
*** 585,594 ****
{
// "unknown" is used for an empty list or dict
if (actual->tt_member != NULL && actual->tt_member != &t_unknown)
! ret = check_type(expected->tt_member, actual->tt_member,
FALSE, where);
}
! else if (expected->tt_type == VAR_FUNC)
{
// If the return type is unknown it can be anything, including
// nothing, thus there is no point in checking.
--- 599,608 ----
{
// "unknown" is used for an empty list or dict
if (actual->tt_member != NULL && actual->tt_member != &t_unknown)
! ret = check_type_maybe(expected->tt_member, actual->tt_member,
FALSE, where);
}
! else if (expected->tt_type == VAR_FUNC && actual != &t_any)
{
// If the return type is unknown it can be anything, including
// nothing, thus there is no point in checking.
***************
*** 596,603 ****
{
if (actual->tt_member != NULL
&& actual->tt_member != &t_unknown)
! ret = check_type(expected->tt_member, actual->tt_member,
! FALSE, where);
else
ret = MAYBE;
}
--- 610,617 ----
{
if (actual->tt_member != NULL
&& actual->tt_member != &t_unknown)
! ret = check_type_maybe(expected->tt_member,
! actual->tt_member, FALSE, where);
else
ret = MAYBE;
}
*** ../vim-8.2.3868/src/vim9compile.c 2021-12-20 15:03:23.247346527 +0000
--- src/vim9compile.c 2021-12-22 10:23:22.215274437 +0000
***************
*** 366,373 ****
|| (actual->tt_type == VAR_FUNC
&& (expected->tt_type == VAR_FUNC
|| expected->tt_type == VAR_PARTIAL)
! && (actual->tt_member == &t_any || actual->tt_argcount < 0)
! && ((actual->tt_member == &t_void)
== (expected->tt_member == &t_void))))
return TRUE;
if ((actual->tt_type == VAR_LIST || actual->tt_type == VAR_DICT)
--- 366,376 ----
|| (actual->tt_type == VAR_FUNC
&& (expected->tt_type == VAR_FUNC
|| expected->tt_type == VAR_PARTIAL)
! && (actual->tt_member == &t_any
! || actual->tt_member == &t_unknown
! || actual->tt_argcount < 0)
! && (actual->tt_member == &t_unknown ||
! (actual->tt_member == &t_void)
== (expected->tt_member == &t_void))))
return TRUE;
if ((actual->tt_type == VAR_LIST || actual->tt_type == VAR_DICT)
***************
*** 412,419 ****
// If the actual type can be the expected type add a runtime check.
// If it's a constant a runtime check makes no sense.
! if (ret == MAYBE || ((!actual_is_const || actual == &t_any)
! && use_typecheck(actual, expected)))
{
generate_TYPECHECK(cctx, expected, offset, where.wt_index);
return OK;
--- 415,421 ----
// If the actual type can be the expected type add a runtime check.
// If it's a constant a runtime check makes no sense.
! if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected))
{
generate_TYPECHECK(cctx, expected, offset, where.wt_index);
return OK;
***************
*** 2547,2554 ****
did_set_arg_type = TRUE;
ufunc->uf_arg_types[arg_idx] = val_type;
}
! else if (check_type(ufunc->uf_arg_types[arg_idx], val_type,
! TRUE, where) == FAIL)
goto erret;
if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
--- 2549,2556 ----
did_set_arg_type = TRUE;
ufunc->uf_arg_types[arg_idx] = val_type;
}
! else if (need_type_where(val_type, ufunc->uf_arg_types[arg_idx],
! -1, where, &cctx, FALSE, FALSE) == FAIL)
goto erret;
if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
*** ../vim-8.2.3868/src/vim9expr.c 2021-12-21 12:32:13.296529989 +0000
--- src/vim9expr.c 2021-12-22 12:54:15.358305817 +0000
***************
*** 415,421 ****
// Global, Buffer-local, Window-local and Tabpage-local
// variables can be defined later, thus we don't check if it
// exists, give an error at runtime.
! res = generate_LOAD(cctx, isn_type, 0, name, &t_unknown);
}
}
}
--- 415,421 ----
// Global, Buffer-local, Window-local and Tabpage-local
// variables can be defined later, thus we don't check if it
// exists, give an error at runtime.
! res = generate_LOAD(cctx, isn_type, 0, name, &t_any);
}
}
}
***************
*** 2846,2851 ****
--- 2846,2852 ----
type_T **typep;
generate_ppconst(cctx, ppconst);
+ ppconst->pp_is_const = FALSE;
// If the types differ, the result has a more generic type.
typep = ((type_T **)stack->ga_data) + stack->ga_len - 1;
*** ../vim-8.2.3868/src/testdir/test_vim9_func.vim 2021-12-21
12:32:13.300529985 +0000
--- src/testdir/test_vim9_func.vim 2021-12-22 12:39:26.895411887 +0000
***************
*** 548,554 ****
END
CheckScriptFailure(lines, 'E1001: Variable not found: b')
! # using script variable requires matching type or type cast
lines =<< trim END
vim9script
var a: any
--- 548,554 ----
END
CheckScriptFailure(lines, 'E1001: Variable not found: b')
! # using script variable requires matching type or type cast when executed
lines =<< trim END
vim9script
var a: any
***************
*** 557,574 ****
enddef
defcompile
END
! CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected
string but got any')
!
! lines =<< trim END
! vim9script
! var a: any
! def Func(arg: string = <string>a)
! echo arg
! enddef
! a = 'works'
! Func()
! END
! CheckScriptSuccess(lines)
# using global variable does not require type cast
lines =<< trim END
--- 557,564 ----
enddef
defcompile
END
! CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
! CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type
mismatch, expected string but got number')
# using global variable does not require type cast
lines =<< trim END
*** ../vim-8.2.3868/src/version.c 2021-12-21 13:30:38.736749839 +0000
--- src/version.c 2021-12-22 09:57:23.547319519 +0000
***************
*** 751,752 ****
--- 751,754 ----
{ /* Add new patch number below this line */
+ /**/
+ 3869,
/**/
--
Warning label on a superhero Halloween costume:
"Caution: Cape does not enable user to fly."
/// Bram Moolenaar -- [email protected] -- 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/20211222131910.7B39B1C0641%40moolenaar.net.