fix(interpreter): initialize assoc/indexed arrays for local -A/-a#886
fix(interpreter): initialize assoc/indexed arrays for local -A/-a#886
Conversation
…hout value `local -A m` followed by `m["a"]="1"` produced an indexed array instead of associative because execute_local_builtin only inserted into call_stack.locals without creating the assoc_arrays entry. Initialize the appropriate array type when local -A or -a is used without a compound assignment value, in both function and global paths. Closes #875
There was a problem hiding this comment.
Pull request overview
Fixes local -A/-a declarations so arrays are initialized with the correct type even when declared without a compound assignment, aligning subsequent element assignments and key expansions with bash behavior.
Changes:
- Initialize
assoc_arrays/arraysentries whenlocal -A name/local -a nameis used without=(...)(both function-scope and global-scope paths). - Add spec coverage for
local -Adeclared first, then populated via element assignments (including keys expansion inside$(...)).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| crates/bashkit/src/interpreter/mod.rs | Ensures local -A/-a creates the corresponding array container upfront so later name[key]=... writes use the correct array type. |
| crates/bashkit/tests/spec_cases/bash/assoc-arrays.test.sh | Adds spec cases validating local -A declare-then-assign and key expansion captured via command substitution. |
Comments suppressed due to low confidence (1)
crates/bashkit/src/interpreter/mod.rs:4514
- The PR updates
localhandling for both associative (-A) and indexed (-a) arrays, but the added spec tests only cover thelocal -A name; name[...]=...path. Please add a regression test forlocal -a arrdeclared without a compound assignment (e.g.,local -a arr; arr[0]=...; echo ${#arr[@]}) to ensure the newflags.arrayinitialization paths stay covered.
let key = &arg[bracket + 1..arg.len() - 1];
let expanded_key = self.expand_variable_or_literal(key);
let resolved_name = self.resolve_nameref(arr_name).to_string();
if let Some(arr) = self.assoc_arrays.get_mut(&resolved_name) {
arr.remove(&expanded_key);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ### assoc_local_keys_in_cmdsub | ||
| myfunc() { | ||
| local -A m | ||
| m["a"]="1" | ||
| m["b"]="2" | ||
| result="$(printf '%s\n' "${!m[@]}" | sort)" | ||
| echo "result: [$result]" | ||
| } |
There was a problem hiding this comment.
Issue #875’s repro involves associative array key expansion inside a process substitution nested within a command substitution (result="$(... < <(... ${!m[@]} ...))"). The new assoc_local_keys_in_cmdsub test covers command substitution but not the nested process substitution case; consider adding a spec test that matches the reported pattern to prevent regressions in that scenario.
Summary
local -A mfollowed bym["a"]="1"produced an indexed array instead of associative, becauseexecute_local_builtinonly inserted intocall_stack.localswithout creating theassoc_arraysentrylocal -Aor-ais used without a compound assignment valueassoc_local_declare_then_assignandassoc_local_keys_in_cmdsubTest plan
cargo test --all-featurespassescargo fmt --checkandcargo clippycleanCloses #875