Mercurial > vim
diff src/vim9type.c @ 26680:1b288eb2fcdc v8.2.3869
patch 8.2.3869: Vim9: type checking for "any" is inconsistent
Commit: https://github.com/vim/vim/commit/fa46ead31abe66494da775921feefece02ce6d95
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Dec 22 13:18:39 2021 +0000
patch 8.2.3869: Vim9: type checking for "any" is inconsistent
Problem: Vim9: type checking for "any" is inconsistent.
Solution: Always use a runtime type check for using "any" for a more
specific type.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 22 Dec 2021 14:30:05 +0100 |
parents | e16806237a70 |
children | 434eaef2ac62 |
line wrap: on
line diff
--- a/src/vim9type.c +++ b/src/vim9type.c @@ -477,7 +477,19 @@ check_typval_type(type_T *expected, typv 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); + { + 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,9 +579,11 @@ check_type_maybe( { // 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. + // 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,10 +599,10 @@ check_type_maybe( { // "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, + ret = check_type_maybe(expected->tt_member, actual->tt_member, FALSE, where); } - else if (expected->tt_type == VAR_FUNC) + 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,8 +610,8 @@ check_type_maybe( { if (actual->tt_member != NULL && actual->tt_member != &t_unknown) - ret = check_type(expected->tt_member, actual->tt_member, - FALSE, where); + ret = check_type_maybe(expected->tt_member, + actual->tt_member, FALSE, where); else ret = MAYBE; }