There seems to be an issue with the following new bash-5.0 feature: A nameref name resolution loop in a function now resolves to a variable by that name in the global scope.
[ Note: "warning: x: circular name reference" messages omitted below. ] While referencing such a nameref works as described, scalar assignment to it modifies the variable from the next higher scope rather than the global one: $ inner() { local -n x=x; x=3; } $ outer() { local x=2; inner; declare -p x; } $ x=1; outer; declare -p x declare -- x="3" # x changed in outer() declare -- x="1" # global x not changed There is odd/broken behavior when `declare' is used to modify such a variable, similar to https://lists.gnu.org/archive/html/bug-bash/2018-07/msg00072.html I think the right thing here would be for `declare' to act as if the `-g` flag had been supplied and modify the variable in the global scope? $ f() { local -n x=x; declare x=(2); x=3; declare -p x; } $ x=1; f; declare -p x declare -an x=([0]="2") # local nameref borked declare -- x="1" # global x not changed $ f() { local -n x=x; declare x=2; }; f -bash: declare: `2': invalid variable name for name reference $ f() { local -n x=x; declare -a x=y; declare -p x; } $ x=1; f; declare -p x declare -an x=() # local nameref borked declare -a x=([0]="y") # global x correct (?) $ unset x; declare -p x declare -- x="1" # original after unset `unset' (no `-n') modifies the nameref: $ f() { local -n x=x; unset x; declare -p x; } $ x=1; f; declare -p x declare -- x declare -- x="1" If the target is an array reference that results in a circular nameref, then neither referencing nor assigning to the nameref works: $ f() { local -n x=x[0]; echo "<$x>"; x=2; } $ x=1; f <> -bash: `x[0]': not a valid identifier