# HG changeset patch # User Bram Moolenaar # Date 1645459203 -3600 # Node ID 27956f5e263cd3c5db0f0e777e0d42ccaead25d3 # Parent 63ed984973c5d24cf3682bc4c89a69e7e987bafa patch 8.2.4431: unnecessary condition when assigning to a variable Commit: https://github.com/vim/vim/commit/993faa34059c7fa304e2d4357c57463765cba6d3 Author: Bram Moolenaar Date: Mon Feb 21 15:59:11 2022 +0000 patch 8.2.4431: unnecessary condition when assigning to a variable Problem: Unnecessary condition when assigning to a variable. Solution: Remove the condition. diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -3409,7 +3409,7 @@ set_var_const( type_T *type = type_arg; typval_T bool_tv; dictitem_T *di; - typval_T *dest_tv = NULL; + typval_T *dest_tv; char_u *varname; char_u *name_tofree = NULL; hashtab_T *ht = NULL; @@ -3503,185 +3503,181 @@ set_var_const( } } - if (dest_tv == NULL) + // Search in parent scope which is possible to reference from lambda + if (di == NULL) + di = find_var_in_scoped_ht(name, TRUE); + + if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) + && var_wrong_func_name(name, di == NULL)) + goto failed; + + if (need_convert_to_bool(type, tv)) { - // Search in parent scope which is possible to reference from lambda - if (di == NULL) - di = find_var_in_scoped_ht(name, TRUE); - - if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) - && var_wrong_func_name(name, di == NULL)) - goto failed; - - if (need_convert_to_bool(type, tv)) - { - // Destination is a bool and the value is not, but it can be - // converted. - CLEAR_FIELD(bool_tv); - bool_tv.v_type = VAR_BOOL; - bool_tv.vval.v_number = tv2bool(tv) ? VVAL_TRUE : VVAL_FALSE; - tv = &bool_tv; - } - - if (di != NULL) + // Destination is a bool and the value is not, but it can be + // converted. + CLEAR_FIELD(bool_tv); + bool_tv.v_type = VAR_BOOL; + bool_tv.vval.v_number = tv2bool(tv) ? VVAL_TRUE : VVAL_FALSE; + tv = &bool_tv; + } + + if (di != NULL) + { + // Item already exists. Allowed to replace when reloading. + if ((di->di_flags & DI_FLAGS_RELOAD) == 0) { - // Item already exists. Allowed to replace when reloading. - if ((di->di_flags & DI_FLAGS_RELOAD) == 0) - { - if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) - && (flags & ASSIGN_FOR_LOOP) == 0) - { - emsg(_(e_cannot_modify_existing_variable)); - goto failed; - } - - if (is_script_local && vim9script - && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0) - { - semsg(_(e_redefining_script_item_str), name); - goto failed; - } - - if (var_in_vim9script && (flags & ASSIGN_FOR_LOOP) == 0) - { - where_T where = WHERE_INIT; - svar_T *sv = find_typval_in_script(&di->di_tv, sid); - - if (sv != NULL) - { - // check the type and adjust to bool if needed - where.wt_index = var_idx; - where.wt_variable = TRUE; - if (check_script_var_type(sv, tv, name, where) == FAIL) - goto failed; - if (type == NULL) - type = sv->sv_type; - } - } - - if ((flags & ASSIGN_FOR_LOOP) == 0 - && var_check_permission(di, name) == FAIL) - goto failed; - } - else + if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) + && (flags & ASSIGN_FOR_LOOP) == 0) { - // can only redefine once - di->di_flags &= ~DI_FLAGS_RELOAD; - - // A Vim9 script-local variable is also present in sn_all_vars - // and sn_var_vals. It may set "type" from "tv". - if (var_in_vim9script || var_in_autoload) - update_vim9_script_var(FALSE, di, - var_in_autoload ? name : di->di_key, flags, - tv, &type, (flags & ASSIGN_NO_MEMBER_TYPE) == 0); + emsg(_(e_cannot_modify_existing_variable)); + goto failed; } - // existing variable, need to clear the value - - // Handle setting internal di: variables separately where needed to - // prevent changing the type. - if (ht == &vimvarht) - { - if (di->di_tv.v_type == VAR_STRING) - { - VIM_CLEAR(di->di_tv.vval.v_string); - if (copy || tv->v_type != VAR_STRING) - { - char_u *val = tv_get_string(tv); - - // Careful: when assigning to v:errmsg and - // tv_get_string() causes an error message the variable - // will already be set. - if (di->di_tv.vval.v_string == NULL) - di->di_tv.vval.v_string = vim_strsave(val); - } - else - { - // Take over the string to avoid an extra alloc/free. - di->di_tv.vval.v_string = tv->vval.v_string; - tv->vval.v_string = NULL; - } - goto failed; - } - else if (di->di_tv.v_type == VAR_NUMBER) - { - di->di_tv.vval.v_number = tv_get_number(tv); - if (STRCMP(varname, "searchforward") == 0) - set_search_direction(di->di_tv.vval.v_number - ? '/' : '?'); -#ifdef FEAT_SEARCH_EXTRA - else if (STRCMP(varname, "hlsearch") == 0) - { - no_hlsearch = !di->di_tv.vval.v_number; - redraw_all_later(SOME_VALID); - } -#endif - goto failed; - } - else if (di->di_tv.v_type != tv->v_type) - { - semsg(_(e_setting_str_to_value_with_wrong_type), name); - goto failed; - } - } - - clear_tv(&di->di_tv); - } - else - { - // Item not found, check if a function already exists. - if (is_script_local && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0 - && lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK) + if (is_script_local && vim9script + && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0) { semsg(_(e_redefining_script_item_str), name); goto failed; } - // add a new variable - if (var_in_vim9script && (flags & ASSIGN_NO_DECL)) + if (var_in_vim9script && (flags & ASSIGN_FOR_LOOP) == 0) { - semsg(_(e_unknown_variable_str), name); - goto failed; + where_T where = WHERE_INIT; + svar_T *sv = find_typval_in_script(&di->di_tv, sid); + + if (sv != NULL) + { + // check the type and adjust to bool if needed + where.wt_index = var_idx; + where.wt_variable = TRUE; + if (check_script_var_type(sv, tv, name, where) == FAIL) + goto failed; + if (type == NULL) + type = sv->sv_type; + } } - // Can't add "v:" or "a:" variable. - if (ht == &vimvarht || ht == get_funccal_args_ht()) + if ((flags & ASSIGN_FOR_LOOP) == 0 + && var_check_permission(di, name) == FAIL) + goto failed; + } + else + { + // can only redefine once + di->di_flags &= ~DI_FLAGS_RELOAD; + + // A Vim9 script-local variable is also present in sn_all_vars + // and sn_var_vals. It may set "type" from "tv". + if (var_in_vim9script || var_in_autoload) + update_vim9_script_var(FALSE, di, + var_in_autoload ? name : di->di_key, flags, + tv, &type, (flags & ASSIGN_NO_MEMBER_TYPE) == 0); + } + + // existing variable, need to clear the value + + // Handle setting internal di: variables separately where needed to + // prevent changing the type. + if (ht == &vimvarht) + { + if (di->di_tv.v_type == VAR_STRING) { - semsg(_(e_illegal_variable_name_str), name); + VIM_CLEAR(di->di_tv.vval.v_string); + if (copy || tv->v_type != VAR_STRING) + { + char_u *val = tv_get_string(tv); + + // Careful: when assigning to v:errmsg and + // tv_get_string() causes an error message the variable + // will already be set. + if (di->di_tv.vval.v_string == NULL) + di->di_tv.vval.v_string = vim_strsave(val); + } + else + { + // Take over the string to avoid an extra alloc/free. + di->di_tv.vval.v_string = tv->vval.v_string; + tv->vval.v_string = NULL; + } goto failed; } - - // Make sure the variable name is valid. In Vim9 script an - // autoload variable must be prefixed with "g:" unless in an - // autoload script. - if (!valid_varname(varname, -1, !vim9script - || STRNCMP(name, "g:", 2) == 0 || var_in_autoload)) + else if (di->di_tv.v_type == VAR_NUMBER) + { + di->di_tv.vval.v_number = tv_get_number(tv); + if (STRCMP(varname, "searchforward") == 0) + set_search_direction(di->di_tv.vval.v_number + ? '/' : '?'); +#ifdef FEAT_SEARCH_EXTRA + else if (STRCMP(varname, "hlsearch") == 0) + { + no_hlsearch = !di->di_tv.vval.v_number; + redraw_all_later(SOME_VALID); + } +#endif goto failed; - - di = alloc(sizeof(dictitem_T) + STRLEN(varname)); - if (di == NULL) - goto failed; - STRCPY(di->di_key, varname); - if (hash_add(ht, DI2HIKEY(di)) == FAIL) + } + else if (di->di_tv.v_type != tv->v_type) { - vim_free(di); + semsg(_(e_setting_str_to_value_with_wrong_type), name); goto failed; } - di->di_flags = DI_FLAGS_ALLOC; - if (flags & (ASSIGN_CONST | ASSIGN_FINAL)) - di->di_flags |= DI_FLAGS_LOCK; - - // A Vim9 script-local variable is also added to sn_all_vars and - // sn_var_vals. It may set "type" from "tv". - if (var_in_vim9script || var_in_autoload) - update_vim9_script_var(TRUE, di, - var_in_autoload ? name : di->di_key, flags, - tv, &type, (flags & ASSIGN_NO_MEMBER_TYPE) == 0); + } + + clear_tv(&di->di_tv); + } + else + { + // Item not found, check if a function already exists. + if (is_script_local && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0 + && lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK) + { + semsg(_(e_redefining_script_item_str), name); + goto failed; + } + + // add a new variable + if (var_in_vim9script && (flags & ASSIGN_NO_DECL)) + { + semsg(_(e_unknown_variable_str), name); + goto failed; + } + + // Can't add "v:" or "a:" variable. + if (ht == &vimvarht || ht == get_funccal_args_ht()) + { + semsg(_(e_illegal_variable_name_str), name); + goto failed; } - dest_tv = &di->di_tv; + // Make sure the variable name is valid. In Vim9 script an + // autoload variable must be prefixed with "g:" unless in an + // autoload script. + if (!valid_varname(varname, -1, !vim9script + || STRNCMP(name, "g:", 2) == 0 || var_in_autoload)) + goto failed; + + di = alloc(sizeof(dictitem_T) + STRLEN(varname)); + if (di == NULL) + goto failed; + STRCPY(di->di_key, varname); + if (hash_add(ht, DI2HIKEY(di)) == FAIL) + { + vim_free(di); + goto failed; + } + di->di_flags = DI_FLAGS_ALLOC; + if (flags & (ASSIGN_CONST | ASSIGN_FINAL)) + di->di_flags |= DI_FLAGS_LOCK; + + // A Vim9 script-local variable is also added to sn_all_vars and + // sn_var_vals. It may set "type" from "tv". + if (var_in_vim9script || var_in_autoload) + update_vim9_script_var(TRUE, di, + var_in_autoload ? name : di->di_key, flags, + tv, &type, (flags & ASSIGN_NO_MEMBER_TYPE) == 0); } + dest_tv = &di->di_tv; if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) copy_tv(tv, dest_tv); else diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4431, +/**/ 4430, /**/ 4429,