comparison src/vim9compile.c @ 25547:ec4df0b982da v8.2.3310

patch 8.2.3310: Vim9: unpack assignment does not mention source of type error Commit: https://github.com/vim/vim/commit/4270d8b7626ff8a7006f6a09c89bc446a3f89d1e Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 7 16:30:42 2021 +0200 patch 8.2.3310: Vim9: unpack assignment does not mention source of type error Problem: Vim9: unpack assignment does not mention source of type error. Solution: Mention the argument number. (closes https://github.com/vim/vim/issues/8719)
author Bram Moolenaar <Bram@vim.org>
date Sat, 07 Aug 2021 16:45:03 +0200
parents 2ae1d5a4ae5c
children 5ab75ca75d21
comparison
equal deleted inserted replaced
25546:465989ba8936 25547:ec4df0b982da
1037 * - "actual" is a type that can be "expected" type: add a runtime check; or 1037 * - "actual" is a type that can be "expected" type: add a runtime check; or
1038 * - return FAIL. 1038 * - return FAIL.
1039 * If "actual_is_const" is TRUE then the type won't change at runtime, do not 1039 * If "actual_is_const" is TRUE then the type won't change at runtime, do not
1040 * generate a TYPECHECK. 1040 * generate a TYPECHECK.
1041 */ 1041 */
1042 static int
1043 need_type_where(
1044 type_T *actual,
1045 type_T *expected,
1046 int offset,
1047 where_T where,
1048 cctx_T *cctx,
1049 int silent,
1050 int actual_is_const)
1051 {
1052 if (expected == &t_bool && actual != &t_bool
1053 && (actual->tt_flags & TTFLAG_BOOL_OK))
1054 {
1055 // Using "0", "1" or the result of an expression with "&&" or "||" as a
1056 // boolean is OK but requires a conversion.
1057 generate_2BOOL(cctx, FALSE, offset);
1058 return OK;
1059 }
1060
1061 if (check_type(expected, actual, FALSE, where) == OK)
1062 return OK;
1063
1064 // If the actual type can be the expected type add a runtime check.
1065 // If it's a constant a runtime check makes no sense.
1066 if ((!actual_is_const || actual == &t_any)
1067 && use_typecheck(actual, expected))
1068 {
1069 generate_TYPECHECK(cctx, expected, offset, where.wt_index);
1070 return OK;
1071 }
1072
1073 if (!silent)
1074 type_mismatch_where(expected, actual, where);
1075 return FAIL;
1076 }
1077
1042 int 1078 int
1043 need_type( 1079 need_type(
1044 type_T *actual, 1080 type_T *actual,
1045 type_T *expected, 1081 type_T *expected,
1046 int offset, 1082 int offset,
1049 int silent, 1085 int silent,
1050 int actual_is_const) 1086 int actual_is_const)
1051 { 1087 {
1052 where_T where = WHERE_INIT; 1088 where_T where = WHERE_INIT;
1053 1089
1054 if (expected == &t_bool && actual != &t_bool
1055 && (actual->tt_flags & TTFLAG_BOOL_OK))
1056 {
1057 // Using "0", "1" or the result of an expression with "&&" or "||" as a
1058 // boolean is OK but requires a conversion.
1059 generate_2BOOL(cctx, FALSE, offset);
1060 return OK;
1061 }
1062
1063 where.wt_index = arg_idx; 1090 where.wt_index = arg_idx;
1064 if (check_type(expected, actual, FALSE, where) == OK) 1091 return need_type_where(actual, expected, offset, where,
1065 return OK; 1092 cctx, silent, actual_is_const);
1066
1067 // If the actual type can be the expected type add a runtime check.
1068 // If it's a constant a runtime check makes no sense.
1069 if ((!actual_is_const || actual == &t_any)
1070 && use_typecheck(actual, expected))
1071 {
1072 generate_TYPECHECK(cctx, expected, offset, arg_idx);
1073 return OK;
1074 }
1075
1076 if (!silent)
1077 arg_type_mismatch(expected, actual, arg_idx);
1078 return FAIL;
1079 } 1093 }
1080 1094
1081 /* 1095 /*
1082 * Check that the top of the type stack has a type that can be used as a 1096 * Check that the top of the type stack has a type that can be used as a
1083 * condition. Give an error and return FAIL if not. 1097 * condition. Give an error and return FAIL if not.
7002 } 7016 }
7003 } 7017 }
7004 else if (*op == '=') 7018 else if (*op == '=')
7005 { 7019 {
7006 type_T *use_type = lhs.lhs_lvar->lv_type; 7020 type_T *use_type = lhs.lhs_lvar->lv_type;
7021 where_T where = WHERE_INIT;
7007 7022
7008 // Without operator check type here, otherwise below. 7023 // Without operator check type here, otherwise below.
7009 // Use the line number of the assignment. 7024 // Use the line number of the assignment.
7010 SOURCING_LNUM = start_lnum; 7025 SOURCING_LNUM = start_lnum;
7026 where.wt_index = var_count > 0 ? var_idx + 1 : 0;
7027 where.wt_variable = var_count > 0;
7011 if (lhs.lhs_has_index) 7028 if (lhs.lhs_has_index)
7012 use_type = lhs.lhs_member_type; 7029 use_type = lhs.lhs_member_type;
7013 if (need_type(rhs_type, use_type, -1, 0, cctx, 7030 if (need_type_where(rhs_type, use_type, -1, where,
7014 FALSE, is_const) == FAIL) 7031 cctx, FALSE, is_const) == FAIL)
7015 goto theend; 7032 goto theend;
7016 } 7033 }
7017 } 7034 }
7018 else 7035 else
7019 { 7036 {