comparison src/evalvars.c @ 24440:d2f9bdd938fa v8.2.2760

patch 8.2.2760: Vim9: no error for changing a for loop variable Commit: https://github.com/vim/vim/commit/f6a8d420a8d2924737f713de046947dcb487550c Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 13 21:48:03 2021 +0200 patch 8.2.2760: Vim9: no error for changing a for loop variable Problem: Vim9: no error for changing a for loop variable. Solution: Make the loop variable read-only. (issue https://github.com/vim/vim/issues/8102)
author Bram Moolenaar <Bram@vim.org>
date Tue, 13 Apr 2021 22:00:05 +0200
parents 78343859f42d
children f388a033e568
comparison
equal deleted inserted replaced
24439:21feee770b96 24440:d2f9bdd938fa
1313 } 1313 }
1314 1314
1315 // ":let $VAR = expr": Set environment variable. 1315 // ":let $VAR = expr": Set environment variable.
1316 if (*arg == '$') 1316 if (*arg == '$')
1317 { 1317 {
1318 if (flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1318 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1319 && (flags & ASSIGN_FOR_LOOP) == 0)
1319 { 1320 {
1320 emsg(_("E996: Cannot lock an environment variable")); 1321 emsg(_("E996: Cannot lock an environment variable"));
1321 return NULL; 1322 return NULL;
1322 } 1323 }
1323 1324
1363 } 1364 }
1364 1365
1365 // ":let &option = expr": Set option value. 1366 // ":let &option = expr": Set option value.
1366 // ":let &l:option = expr": Set local option value. 1367 // ":let &l:option = expr": Set local option value.
1367 // ":let &g:option = expr": Set global option value. 1368 // ":let &g:option = expr": Set global option value.
1369 // ":for &ts in range(8)": Set option value for for loop
1368 else if (*arg == '&') 1370 else if (*arg == '&')
1369 { 1371 {
1370 if (flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1372 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1373 && (flags & ASSIGN_FOR_LOOP) == 0)
1371 { 1374 {
1372 emsg(_(e_const_option)); 1375 emsg(_(e_const_option));
1373 return NULL; 1376 return NULL;
1374 } 1377 }
1375 // Find the end of the name. 1378 // Find the end of the name.
1464 } 1467 }
1465 1468
1466 // ":let @r = expr": Set register contents. 1469 // ":let @r = expr": Set register contents.
1467 else if (*arg == '@') 1470 else if (*arg == '@')
1468 { 1471 {
1469 if (flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1472 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1473 && (flags & ASSIGN_FOR_LOOP) == 0)
1470 { 1474 {
1471 emsg(_("E996: Cannot lock a register")); 1475 emsg(_("E996: Cannot lock a register"));
1472 return NULL; 1476 return NULL;
1473 } 1477 }
1474 ++arg; 1478 ++arg;
3156 set_var_const( 3160 set_var_const(
3157 char_u *name, 3161 char_u *name,
3158 type_T *type, 3162 type_T *type,
3159 typval_T *tv_arg, 3163 typval_T *tv_arg,
3160 int copy, // make copy of value in "tv" 3164 int copy, // make copy of value in "tv"
3161 int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc. 3165 int flags_arg, // ASSIGN_CONST, ASSIGN_FINAL, etc.
3162 int var_idx) // index for ":let [a, b] = list" 3166 int var_idx) // index for ":let [a, b] = list"
3163 { 3167 {
3164 typval_T *tv = tv_arg; 3168 typval_T *tv = tv_arg;
3165 typval_T bool_tv; 3169 typval_T bool_tv;
3166 dictitem_T *di; 3170 dictitem_T *di;
3167 char_u *varname; 3171 char_u *varname;
3168 hashtab_T *ht; 3172 hashtab_T *ht;
3169 int is_script_local; 3173 int is_script_local;
3170 int vim9script = in_vim9script(); 3174 int vim9script = in_vim9script();
3171 int var_in_vim9script; 3175 int var_in_vim9script;
3176 int flags = flags_arg;
3172 3177
3173 ht = find_var_ht(name, &varname); 3178 ht = find_var_ht(name, &varname);
3174 if (ht == NULL || *varname == NUL) 3179 if (ht == NULL || *varname == NUL)
3175 { 3180 {
3176 semsg(_(e_illvar), name); 3181 semsg(_(e_illvar), name);
3185 && name[1] == ':') 3190 && name[1] == ':')
3186 { 3191 {
3187 vim9_declare_error(name); 3192 vim9_declare_error(name);
3188 goto failed; 3193 goto failed;
3189 } 3194 }
3195 if ((flags & ASSIGN_FOR_LOOP) && name[1] == ':'
3196 && vim_strchr((char_u *)"gwbt", name[0]) != NULL)
3197 // Do not make g:var, w:var, b:var or t:var final.
3198 flags &= ~ASSIGN_FINAL;
3199
3190 var_in_vim9script = is_script_local && current_script_is_vim9(); 3200 var_in_vim9script = is_script_local && current_script_is_vim9();
3191 if (var_in_vim9script && name[0] == '_' && name[1] == NUL) 3201 if (var_in_vim9script && name[0] == '_' && name[1] == NUL)
3192 { 3202 {
3193 // For "[a, _] = list" the underscore is ignored. 3203 // For "[a, _] = list" the underscore is ignored.
3194 if ((flags & ASSIGN_UNPACK) == 0) 3204 if ((flags & ASSIGN_UNPACK) == 0)
3218 if (di != NULL) 3228 if (di != NULL)
3219 { 3229 {
3220 // Item already exists. Allowed to replace when reloading. 3230 // Item already exists. Allowed to replace when reloading.
3221 if ((di->di_flags & DI_FLAGS_RELOAD) == 0) 3231 if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
3222 { 3232 {
3223 if (flags & (ASSIGN_CONST | ASSIGN_FINAL)) 3233 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
3234 && (flags & ASSIGN_FOR_LOOP) == 0)
3224 { 3235 {
3225 emsg(_(e_cannot_mod)); 3236 emsg(_(e_cannot_mod));
3226 goto failed; 3237 goto failed;
3227 } 3238 }
3228 3239
3253 di->di_flags &= ~DI_FLAGS_RELOAD; 3264 di->di_flags &= ~DI_FLAGS_RELOAD;
3254 3265
3255 // A Vim9 script-local variable is also present in sn_all_vars and 3266 // A Vim9 script-local variable is also present in sn_all_vars and
3256 // sn_var_vals. It may set "type" from "tv". 3267 // sn_var_vals. It may set "type" from "tv".
3257 if (var_in_vim9script) 3268 if (var_in_vim9script)
3258 update_vim9_script_var(FALSE, di, flags, tv, &type); 3269 update_vim9_script_var(FALSE, di, flags, tv, &type,
3270 (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
3259 } 3271 }
3260 3272
3261 // existing variable, need to clear the value 3273 // existing variable, need to clear the value
3262 3274
3263 // Handle setting internal di: variables separately where needed to 3275 // Handle setting internal di: variables separately where needed to
3351 di->di_flags |= DI_FLAGS_LOCK; 3363 di->di_flags |= DI_FLAGS_LOCK;
3352 3364
3353 // A Vim9 script-local variable is also added to sn_all_vars and 3365 // A Vim9 script-local variable is also added to sn_all_vars and
3354 // sn_var_vals. It may set "type" from "tv". 3366 // sn_var_vals. It may set "type" from "tv".
3355 if (var_in_vim9script) 3367 if (var_in_vim9script)
3356 update_vim9_script_var(TRUE, di, flags, tv, &type); 3368 update_vim9_script_var(TRUE, di, flags, tv, &type,
3369 (flags & ASSIGN_NO_MEMBER_TYPE) == 0);
3357 } 3370 }
3358 3371
3359 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 3372 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT)
3360 copy_tv(tv, &di->di_tv); 3373 copy_tv(tv, &di->di_tv);
3361 else 3374 else