diff options
author | Yegappan Lakshmanan <yegappan@yahoo.com> | 2023-09-29 22:50:02 +0200 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2023-09-29 22:50:02 +0200 |
commit | f3b68d4759a040ed0c4844c279ea3c779b3863ff (patch) | |
tree | a45d5119e1348dc07fc7a2bf98fc9b263b896190 /src/vim9type.c | |
parent | 900894b09a95398dfc75599e9f0aa2ea25723384 (diff) |
patch 9.0.1959: Vim9: methods parameters and types are covariantv9.0.1959
Problem: Vim9: methods parameters and types are covariant
Solution: Support contra-variant type check for object method arguments
(similar to Dart).
closes: #12965
closes: #13221
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Diffstat (limited to 'src/vim9type.c')
-rw-r--r-- | src/vim9type.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/vim9type.c b/src/vim9type.c index 6ca4b292e6..4b8064df1b 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -759,6 +759,8 @@ type_mismatch_where(type_T *expected, type_T *actual, where_T where) where.wt_func_name, typename1, typename2); break; case WT_METHOD: + case WT_METHOD_ARG: + case WT_METHOD_RETURN: semsg(_(e_method_str_type_mismatch_expected_str_but_got_str), where.wt_func_name, typename1, typename2); break; @@ -869,8 +871,15 @@ check_type_maybe( { if (actual->tt_member != NULL && actual->tt_member != &t_unknown) + { + where_T func_where = where; + + if (where.wt_kind == WT_METHOD) + func_where.wt_kind = WT_METHOD_RETURN; ret = check_type_maybe(expected->tt_member, - actual->tt_member, FALSE, where); + actual->tt_member, FALSE, + func_where); + } else ret = MAYBE; } @@ -887,14 +896,20 @@ check_type_maybe( for (i = 0; i < expected->tt_argcount && i < actual->tt_argcount; ++i) + { + where_T func_where = where; + if (where.wt_kind == WT_METHOD) + func_where.wt_kind = WT_METHOD_ARG; + // Allow for using "any" argument type, lambda's have them. if (actual->tt_args[i] != &t_any && check_type( expected->tt_args[i], actual->tt_args[i], FALSE, - where) == FAIL) + func_where) == FAIL) { ret = FAIL; break; } + } } if (ret == OK && expected->tt_argcount >= 0 && actual->tt_argcount == -1) @@ -910,7 +925,10 @@ check_type_maybe( if (actual->tt_class == NULL) return OK; // A null object matches - if (class_instance_of(actual->tt_class, expected->tt_class) == FALSE) + // For object method arguments, do a contra-variance type check in + // an extended class. For all others, do a co-variance type check. + if (class_instance_of(actual->tt_class, expected->tt_class, + where.wt_kind != WT_METHOD_ARG) == FALSE) ret = FAIL; } |