From ad4fac015aae52e444e135969e8d144c43ae4533 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 21 May 2026 20:17:52 +0000 Subject: [PATCH 1/2] shell_parser: drop stale capacity==1 debug_assert in parse_atom BabyVec::with_capacity_in(1) routes through grow_to which floors the allocation at 4 slots, so atoms.capacity() is never 1. The assertion was a stack-fallback check carried over from the Zig port and does not guard any invariant in the Rust implementation. Every single-atom parse (e.g. `echo foo`) tripped it in debug builds since 303cd282b5 introduced BabyVec as the ArenaVec backing. --- src/shell_parser/parse.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/shell_parser/parse.rs b/src/shell_parser/parse.rs index 8ae38c01f92..0961042fb71 100644 --- a/src/shell_parser/parse.rs +++ b/src/shell_parser/parse.rs @@ -1915,10 +1915,7 @@ impl<'bump> Parser<'bump> { Ok(match atoms.len() { 0 => None, - 1 => { - debug_assert!(atoms.capacity() == 1); - Some(ast::Atom::new_simple(atoms.into_iter().next().unwrap())) - } + 1 => Some(ast::Atom::new_simple(atoms.into_iter().next().unwrap())), _ => Some(ast::Atom::Compound(ast::CompoundAtom { atoms: atoms.into_bump_slice(), brace_expansion_hint: has_brace_open && has_brace_close && has_comma, From f86c738b42c1d050c54dc05a2ffa1e86ffd697c5 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Thu, 21 May 2026 20:20:30 +0000 Subject: [PATCH 2/2] test(shell): single-atom parse coverage (ls, echo ~) --- test/js/bun/shell/parse.test.ts | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/js/bun/shell/parse.test.ts b/test/js/bun/shell/parse.test.ts index a091858e9dc..2da7a674bc1 100644 --- a/test/js/bun/shell/parse.test.ts +++ b/test/js/bun/shell/parse.test.ts @@ -59,6 +59,42 @@ describe("parse shell", () => { expect(result).toEqual(expected); }); + test("single atom", () => { + expect(JSON.parse(parse`ls`)).toEqual({ + stmts: [ + { + exprs: [ + { + cmd: { + assigns: [], + name_and_args: [{ simple: { Text: "ls" } }], + redirect: redirect({}), + redirect_file: null, + }, + }, + ], + }, + ], + }); + + expect(JSON.parse(parse`echo ~`)).toEqual({ + stmts: [ + { + exprs: [ + { + cmd: { + assigns: [], + name_and_args: [{ simple: { Text: "echo" } }, { simple: { tilde: {} } }], + redirect: redirect({}), + redirect_file: null, + }, + }, + ], + }, + ], + }); + }); + test("compound atom", () => { const expected = { stmts: [