rust: adopt bon for compile-checked struct and function builders - #32845
rust: adopt bon for compile-checked struct and function builders#32845robobun wants to merge 1 commit into
Conversation
|
Updated 3:07 AM PT - Jul 9th, 2026
❌ @robobun, your commit 3a55eb1 has 3 failures in
🧪 To try this PR locally: bunx bun-pr 32845That installs a local version of the PR into your bun-32845 --bun |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThis PR adds Changesbon builder migration
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Cargo.toml`:
- Around line 350-356: Shorten the inline manifest comment to 3 lines max in
Cargo.toml. Keep the explanation brief and focused on the typestate builder
rationale, removing the longer justification about Default placeholders and
release-build inlining. Locate the existing multi-line comment near the
compile-time-checked builders section and condense it without changing meaning.
In `@src/glob/GlobWalker.rs`:
- Around line 1319-1322: Trim the constructor comment in GlobWalker so it keeps
only the durable invariant about named setters preventing boolean transposition,
and remove the migration-history/out-param note from the nearby documentation on
the GlobWalker constructor/init path. Keep the comment concise and limited to
the non-obvious behavior around GlobWalker::init and only_files, with no
PR-history context.
In `@src/http/AsyncHTTP.rs`:
- Around line 446-448: The builder comment in AsyncHTTP::request-style setup
still references migration history (“used to be” positional parameters); rewrite
it to state only the lasting invariant that named setters prevent accidental
transposition of adjacent &[u8] values like headers_buf and request_body. Keep
the comment durable and non-historical while preserving the rationale for the
API design.
In `@src/install/lockfile/Package.rs`:
- Around line 1677-1681: The inline comment near the lockfile body is too long
and should be compressed to stay within the 3-line guideline. Shorten the
rationale around the live StringBuilder and split-borrow invariant in
Package::... so it keeps only the essential point about reading string_bytes
through the builder while accepting workspace_paths and workspace_versions
directly.
In `@src/runtime/webcore/Blob.rs`:
- Around line 4979-4998: The upload stream branch is still using the store-level
S3 options instead of the parsed per-call upload options, so the request can
ignore caller-provided settings. In the upload path inside Blob.rs, update the
s3_client::upload_stream chain to use the options derived from aws_options (the
same parsed options used by get_credentials_with_options and sibling
upload-stream branches) rather than s3.options, keeping the rest of the
ACL/storage/metadata wiring unchanged.
In `@src/runtime/webcore/fetch/FetchTasklet.rs`:
- Around line 2487-2492: Shorten the doc comment attached to the FetchTasklet
builder rationale so it fits within 3 lines or fewer. Keep the explanation
focused on the builder behavior and the removal of the old Default
implementation, and trim the extra historical/detail sentences in the nearby
comment block.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2ee27aa0-5438-474e-8b3a-4e98caaa29f9
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (41)
Cargo.tomlsrc/bundler/Cargo.tomlsrc/bundler/LinkerContext.rssrc/bundler/LinkerGraph.rssrc/bundler/linker_context/generateCodeForLazyExport.rssrc/bundler/linker_context/scanImportsAndExports.rssrc/glob/Cargo.tomlsrc/glob/GlobWalker.rssrc/http/AsyncHTTP.rssrc/http/Cargo.tomlsrc/http/HTTPContext.rssrc/http/h2_client/ClientSession.rssrc/http/lib.rssrc/install/Cargo.tomlsrc/install/NetworkTask.rssrc/install/lockfile/Package.rssrc/install/lockfile/Package/WorkspaceMap.rssrc/install/npm.rssrc/runtime/Cargo.tomlsrc/runtime/api/glob.rssrc/runtime/cli/audit_command.rssrc/runtime/cli/create_command.rssrc/runtime/cli/filter_arg.rssrc/runtime/cli/pack_command.rssrc/runtime/cli/pm_version_command.rssrc/runtime/cli/pm_view_command.rssrc/runtime/cli/publish_command.rssrc/runtime/cli/run_command.rssrc/runtime/cli/upgrade_command.rssrc/runtime/server/ServerWebSocket.rssrc/runtime/shell/builtin/cp.rssrc/runtime/shell/states/Expansion.rssrc/runtime/webcore/Blob.rssrc/runtime/webcore/fetch.rssrc/runtime/webcore/fetch/FetchTasklet.rssrc/runtime/webcore/s3/client.rssrc/runtime/webcore/s3/download_stream.rssrc/runtime/webcore/s3/simple_request.rssrc/s3_signing/Cargo.tomlsrc/s3_signing/credentials.rssrc/standalone_graph/StandaloneModuleGraph.rs
There was a problem hiding this comment.
Additional findings (outside current diff — PR may have been updated during review):
-
🟡
src/runtime/webcore/s3/simple_request.rs:110-117— These struct doc comments (also onS3HttpDownloadStreamingTaskandFetchOptions) narrate what this PR changed — "This replaces the hand-writtenimpl Defaultthis struct used to carry... Neither construction site used it any more." Per CLAUDE.md, change history belongs in the PR description (where it already appears verbatim); the first sentence ("Every non-Optionfield must be supplied at the construction site; forgetting one is a compile error") is the durable invariant worth keeping, the "This replaces..." tail should be dropped.Extended reasoning...
What this is
The PR adds 6-7-line doc comments above
#[derive(bon::Builder)]on three structs:S3HttpSimpleTask(src/runtime/webcore/s3/simple_request.rs:110-116)S3HttpDownloadStreamingTask(src/runtime/webcore/s3/download_stream.rs:18-24)FetchOptions(src/runtime/webcore/fetch/FetchTasklet.rs:2487-2492)
Each follows the same template, e.g. on
S3HttpSimpleTask:Every non-
Optionfield must be supplied at the construction site; forgetting one is a compile error. This replaces the hand-writtenimpl Defaultthis struct used to carry, which handed out aMaybeUninit::uninit()http(UB toDrop) and acallbackwhose body wasunreachable!("used before being set")purely so..Default::default()struct-update syntax compiled. Neither construction site used it any more.The bolded portion — five of the seven lines — describes what the deleted code looked like and why it was deleted. That is change history.
Why it violates the project convention
Root
CLAUDE.md(line 239, "Code style & idioms") states:Comments carry only durable non-obvious content: invariants, ownership/lifetime contracts, SAFETY justifications... No narrating what the code does, no bug history — that belongs in the PR description.
The "This replaces the hand-written
impl Default..." sentences describe a previous code state that no longer exists in the file. A reader six months from now does not need to know that there used to be anunreachable!("used before being set")placeholder callback — they need to know how to construct the struct today. The PR description already carries this rationale in detail (see "§2.impl Defaultas a construction crutch"), which is exactly where CLAUDE.md says it should live.Step-by-step example
Take
S3HttpDownloadStreamingTask. The comment says:- "Every non-
Optionfield must be supplied at the construction site; forgetting one is a compile error." — durable: tells the reader what#[derive(bon::Builder)]enforces. - "This replaces the hand-written
impl Defaultthis struct used to carry," — history: there is noimpl Defaultin the file any more; "replaces" only makes sense relative to the diff. - "which handed out a
MaybeUninit::uninit()http, a danglingNonNullforcallback_context, and a silent no-opcallback" — history: describes the body of a deleted impl. - "purely so
..Default::default()struct-update syntax compiled." — history: describes the motivation for deleted code. - "The one construction site did not use it any more." — history: describes the state of call sites at the time of the PR.
Sentences 2-5 will be stale the moment this merges (the deleted
Defaultis no longer visible to anyone reading the file), and will become actively misleading if a second construction site is later added.Addressing the counterargument
One verifier argued this is a "deliberate deviation" warning — that it tells future maintainers not to add
Defaultback because doing so was UB. That is a fair reading of the intent, but it is not what the comment says. The comment is phrased as "this replaces X, which did Y" — past-tense narration of the diff — not as "do not addimpl Default:httpisMaybeUninitand a default would be UB toDrop." If the goal is to warn against re-addingDefault, a one-line forward-looking statement to that effect would serve it without the change-history framing. The same verifier conceded the "Neither construction site used it any more" sentence is purely historical and that the "This replaces..." framing "could be tightened" — which is the substance of this nit.The "3 lines max" rule (CLAUDE.md line 268) is weaker grounds on its own — the adjacent
httpfield comment in the same struct is 8 lines — but the no-change-history rule applies cleanly here.Suggested fix
Trim each comment to its durable first sentence, optionally adding a forward-looking warning if desired:
/// Every non-`Option` field must be supplied at the construction site; /// forgetting one is a compile error. No `Default` impl: `http` is /// `MaybeUninit` and a defaulted instance would be UB to `Drop`. #[derive(bon::Builder)] pub struct S3HttpSimpleTask { ... }
This keeps the invariant and the do-not-regress warning while dropping the "used to carry" / "any more" narration that only makes sense relative to this PR's diff.
|
Both claude findings are handled:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/js/bun/glob/scan.test.ts`:
- Around line 940-943: Shorten the explanatory comment in scan.test.ts to 3
lines max while preserving the named-setter invariant for GlobWalker::init. Keep
the core message that each boolean scan option maps to exactly one Rust setter
and that the one-at-a-time fixture tests catch incorrect wiring, but condense
the wording in place.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 011390fb-4906-47f8-a349-773455882555
📒 Files selected for processing (17)
Cargo.tomlsrc/bundler/LinkerGraph.rssrc/glob/GlobWalker.rssrc/http/AsyncHTTP.rssrc/http/HTTPContext.rssrc/install/lockfile/Package.rssrc/install/npm.rssrc/runtime/api/glob.rssrc/runtime/cli/run_command.rssrc/runtime/server/ServerWebSocket.rssrc/runtime/shell/builtin/cp.rssrc/runtime/webcore/fetch/FetchTasklet.rssrc/runtime/webcore/s3/client.rssrc/runtime/webcore/s3/download_stream.rssrc/runtime/webcore/s3/simple_request.rssrc/s3_signing/credentials.rstest/js/bun/glob/scan.test.ts
💤 Files with no reviewable changes (1)
- src/runtime/api/glob.rs
|
CI status for head Three test files have
As before: |
70f87aa to
3ebd017
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/runtime/cli/pm_view_command.rs`:
- Around line 161-164: The comment near pm_view_command::parse should be trimmed
to 3 lines max and remove transient wording like “now-public”; keep only
durable, non-obvious context about why the response is parsed into a
PackageManifest and why last_modified/etag/public_max_age are omitted for pm
view. Rewrite the block in place so it stays concise, references the parse flow
in pm_view_command::parse, and avoids implementation-status language.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 01d435ee-f30d-45a2-977f-9814491a0edd
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (42)
Cargo.tomlsrc/bundler/Cargo.tomlsrc/bundler/LinkerContext.rssrc/bundler/LinkerGraph.rssrc/bundler/linker_context/generateCodeForLazyExport.rssrc/bundler/linker_context/scanImportsAndExports.rssrc/glob/Cargo.tomlsrc/glob/GlobWalker.rssrc/http/AsyncHTTP.rssrc/http/Cargo.tomlsrc/http/HTTPContext.rssrc/http/h2_client/ClientSession.rssrc/http/lib.rssrc/install/Cargo.tomlsrc/install/NetworkTask.rssrc/install/lockfile/Package.rssrc/install/lockfile/Package/WorkspaceMap.rssrc/install/npm.rssrc/runtime/Cargo.tomlsrc/runtime/api/glob.rssrc/runtime/cli/audit_command.rssrc/runtime/cli/create_command.rssrc/runtime/cli/filter_arg.rssrc/runtime/cli/pack_command.rssrc/runtime/cli/pm_version_command.rssrc/runtime/cli/pm_view_command.rssrc/runtime/cli/publish_command.rssrc/runtime/cli/run_command.rssrc/runtime/cli/upgrade_command.rssrc/runtime/server/ServerWebSocket.rssrc/runtime/shell/builtin/cp.rssrc/runtime/shell/states/Expansion.rssrc/runtime/webcore/Blob.rssrc/runtime/webcore/fetch.rssrc/runtime/webcore/fetch/FetchTasklet.rssrc/runtime/webcore/s3/client.rssrc/runtime/webcore/s3/download_stream.rssrc/runtime/webcore/s3/simple_request.rssrc/s3_signing/Cargo.tomlsrc/s3_signing/credentials.rssrc/standalone_graph/StandaloneModuleGraph.rstest/js/bun/glob/scan.test.ts
There was a problem hiding this comment.
I didn't find any issues in this round, but this PR adds a new workspace dependency (bon) and proposes it as a workspace-wide convention across 43 files in six crates — that design decision (and the open CI build failures) warrant a human sign-off.
Extended reasoning...
Overview
This PR introduces the bon crate (compile-time typestate builders) as a workspace dependency and converts 16 functions (~77 call sites) and 3 structs across six crates — bun_glob, bun_http, bun_s3_signing, bun_bundler, bun_install, bun_runtime — from positional arguments / hand-written Default impls to builder chains. It also deletes three impl Default blocks, folds two _with_x sibling functions into their bases, removes a dead FetchOptions.global_this field, and adds a describe block of glob option-flag tests. The PR is explicitly framed as exploratory, evaluating whether bon should become a workspace convention.
Security risks
The diff touches AWS SigV4 canonical-request construction (CanonicalRequest::format in s3_signing/credentials.rs) and S3Credentials::new_value. The conversions are mechanical positional→named with no logic changes, and the parameter values at each call site are preserved verbatim, so I see no new exposure — but signing code is exactly where a transposed argument would be silent and security-relevant, so it merits a careful human pass.
Level of scrutiny
High. Three independent reasons: (1) this is explicitly a convention-setting PR — adopting bon workspace-wide is an architectural choice a maintainer should ratify, not something a bot should approve; (2) it adds three crates to Cargo.lock (bon, bon-macros, strsim); (3) it touches hot/critical paths (HTTP keep-alive socket pooling, fetch tasklet construction, bundler symbol import wiring, S3 signing) where a mis-mapped builder argument would be subtle.
Other factors
All prior review threads (mine and CodeRabbit's) are resolved, and the author has been thorough about verification (cargo check/clippy/fmt, full bun bd, glob test suite re-run post-rebase). However, the most recent robobun CI status (against dae0a97) shows build-rust failing on every platform, which is unresolved. Between the open CI failures, the new dependency, and the convention decision, this needs a human reviewer.
|
Agreed on the human sign-off: adopting a new workspace dependency as a convention is exactly the call this PR is asking a maintainer to make, and the PR description frames it as exploratory for that reason. One correction, because it matters for whoever reviews:
The only genuinely failed job on the current build is On the signing code: I share that concern, which is why |
2a165b3 to
66acf31
Compare
Convert 16 functions (~77 call sites) whose positional parameter lists
have runs of same-typed arguments (transposable without a compile
error) to named-setter builders, and 3 structs whose hand-written
Default impls existed only so ..Default::default() would compile while
required fields got inert placeholder values. bon's typestate builder
makes forgetting a required field a compile error at zero runtime cost.
Folds GlobWalker::init_with_cwd into init (cwd becomes an optional
setter) and RunCommand::run_package_script_foreground_with_shell_path
into run_package_script_foreground (shell_path becomes optional),
deleting the _with_x variant pair. Deletes the three lying Default
impls (FetchOptions, S3HttpSimpleTask, S3HttpDownloadStreamingTask) and
the vestigial Option wrapper on the S3 task vm fields, plus the three
.expect("vm set at task creation") panics that guarded it.
Adds a per-flag Bun.Glob.scan option test: each boolean option maps to
exactly one named setter, so flipping one at a time against a fixed
result set catches a flag wired to the wrong setter.
66acf31 to
3a55eb1
Compare
Exploratory PR evaluating
bon(compile-time typestate builders for structs and functions) as a workspace convention. It converts enough real code, across six crates, to judge the pattern on its own merits, and writes down what the conversion turned up. 16 functions (~77 call sites), 3 structs, all behavior-preserving.The two bug classes this targets
1. Positional arguments of the same type
A positional call with several same-typed arguments type-checks after any transposition. A survey of the workspace (excluding FFI and
#[repr(C)], see below) turned up, among others:CanonicalRequest::format(s3_signing)&[u8], 6 areOption<&[u8]>. Transposinghashanddate(adjacent, same type) signs garbage.S3Credentials::new_valueBox<[u8]>. Transposingaccess_key_idandsecret_access_keycompiles.GlobWalker::init_with_cwdbool. One caller passedfalse, false, false, false, false; another passedtrue, true, false, true, true.HTTPContext::release_sockethostname/target_hostnameandport/target_port.ShellCpTask::createsrc: Vec<u8>, tgt: Vec<u8>, cwd_path: Vec<u8>. Transposingsrc/tgtin acpis data loss.AsyncHTTP::initheaders_buf/request_bodyadjacent, both&[u8]. One caller passedb"", response_buffer, b"".Package::parse_dependencykey_loc: Loc, value_loc: Loc.The clearest evidence this was already costing something is
pm_view_command.rs, where the author had to write inline comments naming every positional argument:Those comments are a builder, written by hand as dead text the compiler cannot check. After:
2.
impl Defaultas a construction crutchA plain struct literal already has compile-checked required fields. The bug is specifically
..Default::default()paired with a hand-writtenDefaultfull of placeholder values, and every instance of it in this PR says so in its own words.FetchOptions(FetchTasklet.rs):S3HttpSimpleTask(simple_request.rs): theDefaultimpl defines a local function as thecallbackplaceholder whose body isa runtime panic standing in for a compile error. Its
httpfield defaults toMaybeUninit::uninit()while theDropimpl callsassume_init, so dropping adefault()is UB.S3HttpDownloadStreamingTask(download_stream.rs):callback_context: NonNull::dangling()and a silent no-opcallback: |_, _, _, _| {}.All three turned out to already be dead: no construction site used
..Default::default()on them any more. This PR deletes the threeimpl Defaults and derives a builder in which the non-Optionfields are required at compile time.The one I did not convert, and why it is the real argument
bun_spawn::WindowsOptions:An
unsafeblock and a runtime non-null assertion exist only so that..Default::default()keeps working. It has 28 construction sites. I did not convert it, because the trap turns out to be viral: those 28 sites buildWindowsOptionsinside async::Options { .., windows: WindowsOptions { loop_, ..Default::default() }, ..Default::default() }whose ownimpl DefaultrequiresWindowsOptions: Default. One placeholderDefaultforces the enclosing struct to grow one too, and you cannot remove the inner one without first removing the outer one.That cascade is, I think, the real answer to why the workspace has 2060
..Default::default()call sites and 535 hand-writtenimpl Defaultblocks. It is the strongest case for making builders a convention, and it is also whyWindowsOptionsneeds its own PR: it requires convertingsync::Optionsfirst.What was converted
Functions (16, ~77 call sites). All are pure positional-to-named conversions; no parameter gained or lost a default that it did not already have.
GlobWalker::init(absorbsinit_with_cwd)bun_globAsyncHTTP::initbun_httpAsyncHTTP::init_syncbun_httpHTTPContext::release_socketbun_httpHTTPContext::existing_socketbun_httpS3Credentials::new_valuebun_s3_signingCanonicalRequest::formatbun_s3_signingLinkerGraph::generate_symbol_import_and_usebun_bundlerPackage::parse_dependencybun_installPackageManifest::parsebun_installServerWebSocket::do_publishbun_runtimes3::uploadbun_runtimes3::upload_streambun_runtimes3::writable_streambun_runtimeRunCommand::run_package_script_foreground(absorbs_with_shell_path)bun_runtimeShellCpTask::createbun_runtimeTwo
_with_xsibling variants became a single builder with an optional member and were deleted:GlobWalker::init_with_cwdfolded intoinit(cwdis now optional, defaulting to the process top-level dir) andRunCommand::run_package_script_foreground_with_shell_pathfolded intorun_package_script_foreground(shell_pathis now optional). Inapi/glob.rs, foldinginit_with_cwdintoinitalso collapsed two copy-pasted "has cwd" / "no cwd" branches into one call via the generated.maybe_cwd()setter. Abonbuilder replaces the_with_xconstructor-name explosion, which is its own defect class.Structs (3):
FetchOptions,S3HttpSimpleTask,S3HttpDownloadStreamingTask. Each derivesbon::Builderand has its hand-writtenimpl Defaultdeleted.Several
#[allow(clippy::too_many_arguments)]attributes on the converted functions are deleted with them.Deliberately skipped
JSGlobalObject::gregorian_date_time_to_ms_utc: 7 consecutivei32, the longest same-type run found, but(year, month, day, hour, minute, second, ms)is the one signature where positional order is universal. A builder there is worse.Repository::checkout: it is a trait method (impl RepositoryExt for Repository);bononly applies to inherent impls.NodeFS::_copy_single_file_sync: has a#[cfg(windows)]-conditional parameter type.write_package_info_object/write_workspace_deps: six byte-identical 12-argument call sites. Six byte-identical builder chains are no better; the right fix is hoisting the invariant context into a struct.output_file::Options: 11 of its 14 construction sites are already full struct literals with no..Default::default(), so they already get compile-checked required fields. The fix there is 3 call sites, not a 270-line conversion.WindowsOptionsandsync::Options: the viral-Defaultcascade above; needs its own PR.#[repr(C)], everything in the*_jscand*_syscrates, everyextern "C"and// HOST_EXPORT(..)function, and the fn-pointer hook tables: their layouts and signatures are fixed by the C++ side. That boundary, not caution, is the real ceiling on how much of the workspace this can reach.Cost
Cargo.lock:bon,bon-macros, andstrsim.bon-macros' heavy dependencies (syn,quote,proc-macro2,darling) were already in the tree viastrumandenumset..call()/.build()into the same code as the positional call or struct literal. Upstream documents this with generated assembly at https://bon-rs.com/guide/benchmarks/runtime, and this workspace'slto = "fat"+codegen-units = 1release profile is stronger than what those benchmarks assume.cargo check --workspacewall time.Verification
cargo check --workspace: cleancargo clippy --workspace: clean. The workspace denies ~50 clippy lints;bon's generated code passes all of them, includingneedless_pass_by_value,large_types_passed_by_value,redundant_clone, andunreachable_pub.cargo check --workspace --target x86_64-pc-windows-msvc: cleancargo fmt --check: cleanbun bd(full debug + ASan build): succeeds.Bun.Glob(..).scanSync,Bun.serve+fetch, and the firsttest/js/bun/glob/scan.test.tscases were exercised against the built binary.Rebase onto main (2026-06-28)
Rebased onto
a1c39ded9b(25 upstream commits) and squashed this branch's 13 commits, most of which were review fixups, into one. Two conflicts, both append/append:src/runtime/server/ServerWebSocket.rs: Bun.serve websocket: make publish() return 0/-1 on subscriber backpressure #32889 rewrotedo_publish's body (it now maps an aggregatedSendStatusinstead of a bool) and its doc comment. The signature is unchanged, so the resolution keeps Bun.serve websocket: make publish() return 0/-1 on subscriber backpressure #32889's body and doc and re-adds the#[builder]attribute; all six callers are unaffected.test/js/bun/glob/scan.test.ts: glob: match explicitly-named dotfiles and resolve literal paths through symlinks #32853 appended adescribeblock at the same end-of-file position as theglob.scan option flagsblock this PR adds. Both are kept.Because #32853 also changed glob dotfile and symlink semantics, the verification was rerun in full against the rebased tree rather than assumed:
cargo check --workspace,cargo clippy --workspace,cargo fmt --check, and a completebun bdall pass, and the mergedtest/js/bun/glob/scan.test.ts(#32853's new behavior tests plus this PR's flag tests, 197 tests) passes against the rebuilt binary with 0 failures. #32853's own new tests (wildcard pattern "**/*.txt" still hides dotfiles by default,wildcard segment still respects followSymlinks:false) assert the same semantics the flag tests here rely on.Rebase onto main (2026-07-01)
Rebased again onto
eba370b692(75 upstream commits, including the JSON parser rewrite in #33032 and the WebKit bump in #33133). One conflicting file:src/install/lockfile/Package.rs, and this one was non-trivial.#33032 changed
parse_dependencyitself: it deleted thevalue_loc: bun_ast::Locparameter (the value location is now derived inside the body via a newvalue_loc_of()helper) and restructured the enclosing loop to iterateJsonObjectStringRows, sokey_locbecame a loop binding rather than anExprfield. The resolution takes main's new signature and control flow verbatim and removes the now-nonexistent.value_loc(..)setter from all three call sites; the doc comment this PR had added, whose rationale was "key_loc/value_locare an adjacent same-typed pair", became false along with the parameter and was rewritten.Two build prerequisites from main are worth knowing about if you build this branch: the new
bun_parserscrate'sbuild.rsneedsbun bd --configure-onlyto have generatedjson_byte_class.rs, andgenerated_classes.rsmust be regenerated for #33144's newBuildArtifactcached field. Neither is specific to this PR.Verification was rerun in full on the rebased tree:
cargo check --workspace,cargo clippy --workspace,cargo fmt --check,prettier, and a completebun bdall pass; the mergedtest/js/bun/glob/scan.test.ts(197 tests) passes against the rebuilt binary. Because the only real conflict was inside the package.json dependency parser, it was also runtime-verified directly: a local workspace install (aworkspaces: ["packages/*"]glob plusdependencies/peerDependencies/peerDependenciesMetaon a member) exercises this PR's convertedGlobWalker::initand all three hand-mergedparse_dependencycall sites, including thepeerDependenciesMeta-only synthesis path, and produces a correct lockfile on the rebuilt binary.Rebase onto main (2026-07-09)
Rebased onto
b05b4fab0e(104 upstream commits). Two conflicting files, both in thefetch()path, and both one change: main added afetch(url, {timeout: ms})option, threading a newidle_timeout_seconds: Option<c_uint>field throughFetchOptionsand intoasync_http::Options(alongside a newproxy_settingsfield there).src/runtime/webcore/fetch/FetchTasklet.rs: the struct definition picked upidle_timeout_secondsin the auto-merge (it isOption<T>, so bon auto-generates.maybe_idle_timeout_seconds()with no attribute needed); theimpl Default for FetchOptionsthis PR deletes conflicted because main added the new field there, so it stays deleted; and theAsyncHTTP::init()call picks up main's two new fields in the innerasync_http::Optionsliteral.src/runtime/webcore/fetch.rs: theFetchOptions::builder()chain gains a.maybe_idle_timeout_seconds(idle_timeout_seconds)setter right where main put the field in the struct literal. Main's side also re-mentioned theglobal_thisfield this PR proves dead and deletes; that stays deleted.Verification rerun in full on the rebased tree:
cargo check --workspace,cargo clippy --workspace,cargo fmt --check,prettier, and a completebun bdall pass. Because the only conflicts were in thefetch()path, runtime-verified directly: afetch(url, {timeout: 5000})roundtrip against a localBun.serveexercises the exact merged code and succeeds. The workspacebun installsmoke and the per-flagscan.test.tstests also pass against the rebuilt binary.no test proof · iteration 12 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/js/bun/glob/scan.test.ts