Mercurial > vim
diff src/vim9compile.c @ 30576:72e6073a2822 v9.0.0623
patch 9.0.0623: error for modifying a const is not detected at compile time
Commit: https://github.com/vim/vim/commit/fa1039760e8c1a0c7a2a722160bd3d71a4736e61
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Sep 29 19:14:42 2022 +0100
patch 9.0.0623: error for modifying a const is not detected at compile time
Problem: Error for modifying a const is not detected at compile time.
Solution: Add TTFLAG_CONST and check for it in add() and extend().
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 29 Sep 2022 20:15:05 +0200 |
parents | bff0506a0911 |
children | ee039a6049ff |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -463,6 +463,29 @@ need_type( } /* + * Set type of variable "lvar" to "type". If the variable is a constant then + * the type gets TTFLAG_CONST. + */ + static void +set_var_type(lvar_T *lvar, type_T *type_arg, cctx_T *cctx) +{ + type_T *type = type_arg; + + if (lvar->lv_const && (type->tt_flags & TTFLAG_CONST) == 0) + { + if (type->tt_flags & TTFLAG_STATIC) + // entry in static_types[] is followed by const type + type = type + 1; + else + { + type = copy_type(type, cctx->ctx_type_list); + type->tt_flags |= TTFLAG_CONST; + } + } + lvar->lv_type = type; +} + +/* * Reserve space for a local variable. * Return the variable or NULL if it failed. */ @@ -497,7 +520,12 @@ reserve_local( lvar->lv_name = vim_strnsave(name, len == 0 ? STRLEN(name) : len); lvar->lv_const = isConst; - lvar->lv_type = type; + if (type == &t_unknown || type == &t_any) + // type not known yet, may be inferred from RHS + lvar->lv_type = type; + else + // may use TTFLAG_CONST + set_var_type(lvar, type, cctx); // Remember the name for debugging. if (GA_GROW_FAILS(&dfunc->df_var_names, 1)) @@ -2304,19 +2332,22 @@ compile_assignment(char_u *arg, exarg_T } else { + type_T *type; + // An empty list or dict has a &t_unknown member, // for a variable that implies &t_any. if (rhs_type == &t_list_empty) - lhs.lhs_lvar->lv_type = &t_list_any; + type = &t_list_any; else if (rhs_type == &t_dict_empty) - lhs.lhs_lvar->lv_type = &t_dict_any; + type = &t_dict_any; else if (rhs_type == &t_unknown) - lhs.lhs_lvar->lv_type = &t_any; + type = &t_any; else { - lhs.lhs_lvar->lv_type = rhs_type; + type = rhs_type; inferred_type = rhs_type; } + set_var_type(lhs.lhs_lvar, type, cctx); } } else if (*op == '=')