Skip to content

test(spec): unset scope cases from the bash oracle - #2607

Merged
chaliy merged 1 commit into
mainfrom
claude/unset-local-scope
Oct 8, 2026
Merged

chaliy merged 1 commit into
mainfrom
claude/unset-local-scope

Conversation

@chaliy

@chaliy chaliy commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

unset NAME now follows bash's dynamic scope:

  • It removes the innermost local binding and leaves the outer one, so a called function's unset v uncovers the caller's local, or the global, instead of deleting both.
  • A local that the running function declared itself stays invisible for the rest of the call rather than exposing the outer value (bash's behavior); the outer value comes back when the function returns.
  • Unsetting a local array restores the outer array instead of discarding it.

Why

Debian-oracle case functions-dynamic-scope-and-unset, and two bashbox local-scope cases that were skipped. A helper that does unset flag to clear state was wiping the caller's and the global value, and nothing restored them.

Before / After

f() { local v=f; g; echo "f sees ${v:-none}"; }
g() { unset v; echo "after unset ${v:-none}"; }
v=global; f; echo "global: $v"
Before After (matches bash)
after unset none global
f sees none global
global: (empty) global

New spec file unset-local-scope.test.sh (4 cases), verified against bash 5.2; bashbox_local_scope_unset_from_a_callee_uncovers_the_global and ..._a_global_scalar lose their skip markers.

Risk

Medium-low. CallFrame gains an unset_locals set, checked first in the regular-variable lookup. A name never declared local is unset globally as before. The full spec corpus (3125 cases), lib, integration and bash-comparison suites pass.

Checklist

  • Failing spec first, verified against real bash
  • cargo test -p bashkit --lib, --test integration, bash_comparison
  • cargo clippy --all-targets -D warnings, cargo fmt --check, just check-okf
  • knowledge/log.md updated

https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA


Generated by Claude Code

@chaliy chaliy self-assigned this Oct 7, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit bbc5194 Commit Preview URL

Branch Preview URL
Oct 08 2026, 12:50 AM

@chaliy
chaliy force-pushed the claude/unset-local-scope branch from cc7871e to 1ee92d1 Compare October 8, 2026 00:22
The behavior landed with the declaration engine (#2597); these cases pin it:
a callee's `unset` uncovers the caller's binding for scalars and arrays, and a
local unset in its own scope stays invisible for the rest of the call.

Claude-Session: https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA
@chaliy
chaliy force-pushed the claude/unset-local-scope branch from 1ee92d1 to bbc5194 Compare October 8, 2026 00:49

chaliy commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on main: #2597's declaration engine already landed this behavior, so the interpreter change here was redundant and conflicted with it. Reduced the PR to the spec cases, which pass unmodified on current main and keep the behavior pinned.


Generated by Claude Code

@chaliy chaliy changed the title fix(interpreter): unset removes the innermost binding, not every one test(spec): unset scope cases from the bash oracle Oct 8, 2026
@chaliy
chaliy merged commit f48ae85 into main Oct 8, 2026
33 checks passed
@chaliy
chaliy deleted the claude/unset-local-scope branch October 8, 2026 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant