Correct priority of universal and global variable setting

When setting a variable without a specified scope, we should give priority
to an existing local or global above an existing universal variable with
the same name.

In 16fd780484 there was a regression that
made universal variables have priority.

Fixes #5883
This commit is contained in:
ridiculousfish 2019-05-25 17:15:50 -07:00
parent cf9b2ff1e5
commit 2924751488
4 changed files with 36 additions and 6 deletions

View File

@ -1087,16 +1087,19 @@ int env_stack_impl_t::set(const wcstring &key, env_mode_flags_t mode, wcstring_l
} else { } else {
DIE("Unknown scope"); DIE("Unknown scope");
} }
} else if (env_node_ref_t node = find_in_chain(locals_, key)) {
// Existing local variable.
set_in_node(node, key, std::move(val), flags);
} else if (env_node_ref_t node = find_in_chain(globals_, key)) {
// Existing global variable.
set_in_node(node, key, std::move(val), flags);
} else if (uvars() && uvars()->get(key)) { } else if (uvars() && uvars()->get(key)) {
// Modifying an existing universal variable. // Existing universal variable.
set_universal(key, std::move(val), query); set_universal(key, std::move(val), query);
*out_needs_uvar_sync = true; *out_needs_uvar_sync = true;
} else { } else {
// The user did not request any scope. // Unspecified scope with no existing variables.
// Find the scope. auto node = resolve_unspecified_scope();
env_node_ref_t node = find_in_chain(locals_, key);
if (!node) node = find_in_chain(globals_, key);
if (!node) node = resolve_unspecified_scope();
assert(node && "Should always resolve some scope"); assert(node && "Should always resolve some scope");
set_in_node(node, key, std::move(val), flags); set_in_node(node, key, std::move(val), flags);
} }

View File

@ -8,3 +8,6 @@ fish: for: Variable name 'a,b' is not valid. See `help identifiers`.
for a,b in y 1 z 3; echo $a,$b; end for a,b in y 1 z 3; echo $a,$b; end
^ ^
####################
# Global vs Universal Unspecified Scopes

View File

@ -330,4 +330,20 @@ logmsg Variable names in other commands
# Test invalid variable names in loops (#5800) # Test invalid variable names in loops (#5800)
for a,b in y 1 z 3; echo $a,$b; end for a,b in y 1 z 3; echo $a,$b; end
logmsg Global vs Universal Unspecified Scopes
set -U __fish_test_global_vs_universal universal
echo "global-vs-universal 1: $__fish_test_global_vs_universal"
set -g __fish_test_global_vs_universal global
echo "global-vs-universal 2: $__fish_test_global_vs_universal"
set __fish_test_global_vs_universal global2
echo "global-vs-universal 3: $__fish_test_global_vs_universal"
set -e -g __fish_test_global_vs_universal
echo "global-vs-universal 4: $__fish_test_global_vs_universal"
set -e -U __fish_test_global_vs_universal
echo "global-vs-universal 5: $__fish_test_global_vs_universal"
true true

View File

@ -58,3 +58,11 @@ a:b a b
#################### ####################
# Variable names in other commands # Variable names in other commands
####################
# Global vs Universal Unspecified Scopes
global-vs-universal 1: universal
global-vs-universal 2: global
global-vs-universal 3: global2
global-vs-universal 4: universal
global-vs-universal 5: