Repository navigation
Conversation
…ke client, bun-error, and the build scripts Each removed item has no reference in src/, packages/, scripts/, test/ or the generated code outside its own definition. The generated C++ only loses lines (ZigGeneratedClasses, JSSink). WebCoreJSBuiltins is byte-identical.
|
Warning Review paused — included plan limit reachedKeep your review moving with free on-demand reviews.
On-demand reviews are free for the next 2 days.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Promotion and pricing detailsOn-demand reviews are free for the next 2 days. After that, they cost $0.25 per reviewed file. Review limit detailsOr wait 34 seconds for your next included review. Limit details: You’ve used all 10 included reviews currently available. Review configuration: ⚙️ Run configurationConfiguration used: Repository: oven-sh/bun/.coderabbit.yaml Review profile: ASSERTIVE Plan: Essentials Run ID: 📒 Files selected for processing (32)
Comment |
|
Updated 3:32 PM PT - Sep 18th, 2026
❌ @robobun, your commit dc1a38f has 1 failures in
🧪 To try this PR locally: bunx bun-pr 43378That installs a local version of the PR into your bun-43378 --bun |
|
Status: needs a rebase
State of dc1a38f:
|
There was a problem hiding this comment.
I reviewed this PR and didn't find any bugs. Because it edits the class and sink generators (which shape every generated wrapper class) across 32 files and I could not run a full build here, a human look would still be worthwhile.
What was reviewed:
- Grepped
src/,packages/,scripts/,test/for every removed symbol (__ptrOffset,__createWithInitialValues,__createWithValuesAndInitialValues,onStructuredCloneTransfer,JSSink_isSink,BUN_NATIVE_MODULE_START_INDEX,bake_empty_file,hasEventListeners(),offsetOfWrapped,mainWebSocket,renderAbort,highlightColumnEnd,ninjaFile) — no remaining references;ShellBindings.cppuses the survivingjsvalueArrayoverload and onlyJS<Name>Sink::Sinkis read. - Checked the 66 removed
JSBuffer.cppdeclarations: definitions precede first use insidenamespace WebCore, and the removed lines sat at global scope before line 304. - Checked the
invokeFunctorPropagatingExceptionIfNecessarypointer-overload removal: all remaining callers passJSGlobalObject&. - Checked the
bundler_plugin.hremoval:wrapper.his consumed only bycopy_headers.ts, which regeneratesheaders/before bindgen; the crate ships pre-generatedsrc/sys.rsand has nobuild.rs.
Extended reasoning...
Overview
This is a pure deletion sweep: 32 files, +15/-455. It removes unused overloads, extern "C" factories and the __ptrOffset export from generate-classes.ts; unused constants, a createPrototype, a stale extern decl and dead includes from generate-jssink.ts; two never-matching regex rewrites and an unread #define from bundle-modules.ts; an unreachable useThis arrow branch and an impossible "export type" comparison from bundle-functions.ts; write-only pointer metadata from cppbind.ts; 66 global-scope JSC_DECLARE_HOST_FUNCTION prototypes from JSBuffer.cpp; an unused hostName() in WebSocket.cpp; no-arg/ASCIILiteral hasEventListeners overloads; a duplicate pointer overload in JSDOMExceptionHandling.h; unused using aliases; unused TS types in private.d.ts, builtins.d.ts, bake.private.d.ts; write-only fields in the bake client, bun-error, the debug adapter framer, and the build scripts; and a stale committed copy of bundler_plugin.h (now gitignored).
Security risks
None identified. Nothing in the diff touches auth, crypto, TLS, permissions, input parsing, or user-reachable control flow. The only runtime-JS changes are removing a write-only remapped flag and a write-only mainWebSocket singleton in the bake client, and retyping a local in CommonJS.ts from a deleted interface to any without changing the code that uses it.
Level of scrutiny
Moderate. Each removal is individually trivial, but the generator edits multiply across ~94 generated classes and all sink classes, so a single missed reference would be a link/compile failure rather than a runtime bug. I verified by grep that none of the removed C++/extern names have remaining references, that ShellBindings.cpp uses the overload that survives, that every remaining invokeFunctorPropagatingExceptionIfNecessary caller passes a reference, and that each removed JSBuffer.cpp prototype's definition appears before its first use in the hash tables. I could not run bun bd or tsc in this environment, so compile-level confirmation rests on the author's stated verification and CI; that is the main reason for deferring rather than approving.
Other factors
Behavior-preservation checks per REVIEW.md: the bundle-functions.ts useThis constant was hard-coded true, so the emitted text is unchanged; the tokenizer regex at line 105 cannot produce "export type" and no builtin file starts a line with export type; nativeStartIndex remains live for its other consumers; the Config.roots field has no Rust writer in src/runtime/bake. The bun-native-plugin crate consideration from the ruled-out list holds up: wrapper.h is only read by copy_headers.ts after it regenerates headers/, and the crate has no build.rs, so consumers of the published crate use the checked-in src/sys.rs. No tests are added, which is appropriate for a deletion-only change with no behavior to assert.
|
Thanks for the review. On the open point (no build in the review environment): CI compiled and linked this commit on all 13 build lanes (macOS x64 and arm64, Linux glibc, musl and ASAN, Android, FreeBSD, Windows x64 and arm64). A reference to a removed C++ or generated symbol that exists on only one platform would fail one of those lanes, and none did. The one red test so far, |
| JSC_DECLARE_HOST_FUNCTION(constructJSBuffer); | ||
| JSC_DECLARE_HOST_FUNCTION(callJSBuffer); | ||
|
|
||
| JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_alloc); |
There was a problem hiding this comment.
My guess is that we might as well keep these for future use
There was a problem hiding this comment.
These prototypes cannot serve a future use as written. They are at global scope (line 110 is before namespace Bun { at line 187), so they declare ::jsBufferPrototypeFunction_*. The real functions are WebCore::jsBufferPrototypeFunction_*: every JSC_DEFINE_HOST_FUNCTION for them is inside the namespace WebCore { that opens at line 455, and the binary only has the WebCore:: symbols (nm -C shows WebCore::jsBufferPrototypeFunction_compare(...) and no global one).
So a call through one of these prototypes does not link, and an unqualified use at global scope is ambiguous because of using namespace WebCore; at line 103. The definitions also come before the hash tables that use them, so nothing needs a forward declaration today.
If you want forward declarations in this file, the form that works is inside namespace WebCore. Tell me which you prefer and I will do it: keep the deletion, move them into the namespace, or restore them unchanged.
### Problem - `hasExportStar` in `src/runtime/bake/hmr-module.ts` has no caller. Its only call site is a block that #18109 commented out on 2025-03-14. The `availableExportKeys` local above that block is read only by the commented-out code. - `firstConnection` in `src/runtime/bake/client/websocket.ts` is assigned once and never read. - No lint reports them. Earlier sweeps ran `tsc --noUnusedLocals` over `src/js` and `scripts` only, not over `src/runtime/bake`. ### Fix - Delete `hasExportStar`, the commented-out check, `availableExportKeys`, and `firstConnection`. 2 files, 40 lines removed. - Correct because the bundler already drops `hasExportStar`. The generated `bake.client.js`, `bake.server.js` and `bake.error.js` differ from `main` only by the two removed local declarations. - Verified: `tsc -p src/runtime/bake/tsconfig.json --noUnusedLocals` no longer reports either file. `test/bake/dev/esm.test.ts` (17 pass), `hot.test.ts` (11 pass) and `bundle.test.ts` (23 pass) with the debug build. Behaviour change: none ### Background - `hmr-module.ts` is the module loader that the dev server sends to the browser and to the SSR realm. `parseEsmDependencies` walks the dependency list of an ES module. Each entry carries the export names that the importer uses. - The removed check compared those names with the exports of the dependency and threw a `SyntaxError` for a missing one. It has been off for 18 months. A missing export fails at the use site. - A deletion has one possible place, so no other design was weighed. ### Downsides - The commented-out check was the only sketch of export verification in the HMR runtime. A person who wants to build it starts from the history of #18109. <details><summary>Notes</summary> #### Why this run is small Every other hit of this run is live, is platform code with a user on another target, or is a line that one of the 34 open dead-code pull requests already deletes. Each removed line here was checked against those diffs. #40492 and #43378 touch `websocket.ts` in other hunks. #### Scans of this run, all clean or already claimed - Debug objects linked again with `--gc-sections --print-gc-sections`, then `llvm-symbolizer` for `file:line`. 20,668 discarded functions in bun's objects. The Rust ones outside macros and trait impls are Windows or macOS helpers, or claimed (#40824, #40557, #40232). The C++ ones are claimed, are template instantiations, or have a Rust caller on another target (`bsd_socket_export`, `posix_spawnattr_reset_signals`). - Rust functions that never get a symbol (generic or `#[inline]`, never instantiated), found by comparing every `fn` line with the DWARF declaration lines of all emitted functions. 86 hits outside `cfg`, trait impls and `#[inline(always)]`. All are Windows-only, test-only (the outbound half of `api/bun/h2/connection.rs`), or claimed. - `clang -fsyntax-only -Wunused-function -Wunused-macros -Wunused-template -Wunused-member-function` over 588 translation units and the 69 unified ones (the build passes `-Wno-unused-function`). 3 functions and 6 macros. `formatStackTraceToJSValueWithoutPrepareStackTrace`, `hostName`, `G_TRUE`, `G_FALSE`, `MAX_LABELS` and `us_ioctl` are claimed (#40367, #43378, #40492, #40294). `us_quic_send_one` is used under the non-Linux `#if` branch. - A whole-program C++ reference index (`c-index-test -index-file`, 657 translation units, 32,018 symbols declared in bun's tree). 8,711 have no recorded reference. After filters for template-dependent uses, `extern "C"`, virtual methods and names that WebKit headers use, 78 remain. All are index artifacts (typedef struct tags, primary templates with used specializations, `requires` clauses) or one-line getters in files that open pull requests rewrite. - `tsc --noUnusedLocals` over `src/js`, `scripts`, `src/codegen`, `src/runtime/bake`, `src/node-fallbacks` and the sources of each package. The hits outside this change are claimed (#40122, #41169, #41385, #40492, #43778) or are loop variables. - Regex scans for struct fields with no read and for `bool` or `Option` fields that only ever get one constant. Nothing new after #43745. - Exports of `src/js` modules and builtin functions with no mention in another file: none. - Files that nothing includes, imports or names: none outside `.idl` copies (#41064). `src/symbols.txt`, `symbols.def` and the `package.json` scripts name nothing that is gone. No `#if 0`. </details> <!-- robobun:evidence:begin --> --- **no test proof** · iteration 1 · the description declares no behaviour change, so there is no failing test to prove; the existing suite in CI is the check <!-- robobun:evidence:end -->
… and the CI pipeline script (#43976) Behaviour change: none ### Problem - Eleven files hold items that nothing reads or calls: write-only fields, an uncalled method, four unused types, and CI options that are parsed and dropped. - No tool reports them. C and C++ have no dead-code lint. TypeScript counts `x += n` as a read. The Rust types come from a macro. ### Fix - TypeScript: remove `DataViewReader.u16()`, `DataViewWriter.capacity`, the `totalCount` local in `updateBuildErrorOverlay`, and a commented-out block from 2024 in `src/js/node/dgram.ts`. - C and C++: remove `us_udp_socket_t.connected`, `us_quic_stream_s.headers_delivered` and `Http2ResponseData::totalSize` (each is only written), and `#undef FD_BITS` (nothing defines it). - Rust and CI: remove the opaque types `us_loop_t`, `us_socket_context_t`, `us_udp_socket_t`, `us_udp_packet_buffer_t` from `src/uws_sys/lib.rs`. In `.buildkite/ci.ts`, remove `dryRun`, `Platform.features`, four emoji entries, and the union members `"amazonlinux"` and `"eol"`. - Verified: `rg -w` for each symbol over `src`, `packages`, `scripts`, `test` and `build/debug/codegen` finds no other use. `bun bd`, `bun run rust:check-all` (12 targets) and `tsc` pass. Self-reviewed: 1 concern raised, 1 addressed. ### Background - `DataViewReader` and `DataViewWriter` decode and encode the binary messages between the dev server and its browser client. - `us_udp_socket_t` and `us_quic_stream_s` are private C structs of uSockets. Rust holds them as opaque pointers, so no Rust struct mirrors their layout. - `bun_core::opaque_extern!` declares a zero-sized Rust type for a C struct. Rust code names `Loop`, `udp::Socket` and `udp::PacketBuffer`, not the four removed types. ### Downsides - None found. Checked each removed symbol for users in Rust, C, C++, TypeScript, generated code, tests, and open pull requests. <details><summary>Notes</summary> **Evidence per removal** | Item | Evidence | | --- | --- | | `DataViewReader.u16()` | `rg '\.u16\('` over `src/runtime/bake`, `test/bake`, `test/cli/inspect`: no hit. | | `DataViewWriter.capacity` | The only hit of `.capacity` in the bake TypeScript is the assignment in the constructor. `initCapacity` is the only caller of the constructor. | | `totalCount` | Two hits: the declaration and one `+=`. | | `dgram.ts` block | `git blame`: 589f941, 2024-04-26. `replaceHandle` and `startListening` are not defined in the file. | | `us_udp_socket_t.connected` | Two hits, both `udp->connected = 0;`. | | `us_quic_stream_s.headers_delivered` | Two hits in `quic.c`: the field and one `= 1`. The struct is private to `quic.c`. | | `Http2ResponseData::totalSize` | One member access: `data.totalSize = totalSize;`. The other hits of `totalSize` are the function parameter. | | `#undef FD_BITS` | The only hit of `FD_BITS` in `src` and `packages`. | | Four opaque types | Each name has one non-comment hit in all Rust sources and generated Rust: the macro call. | | `dryRun` | Four hits in `ci.ts`: the field, two assignments, one destructure. Nothing reads the binding. | | `Platform.features` | One hit. | | Emoji, `Distro`, `Tier` entries | No platform in `ci.ts` or image in `scripts/build/ci-images/spec.ts` carries them. `Emoji` is `keyof typeof emojiMap`, so a remaining caller would fail `tsc -p scripts/tsconfig.json`. It passes. | **Taken out because an open pull request uses or removes the item** - `DataViewWriter.u8()`: dead on main, but #42075 adds its first caller (`check.u8(IncomingMessageId.check_errors)` in `hmr-runtime-error.ts`). Git merges the two without a conflict, so the method stays. The tree that results from a merge of this branch with #42075 has no type error for `u8`. - `declare module "bun:wrap"` in `bake.private.d.ts`: no importer, but #39488 already has the same hunk. **Tests run with the debug build, all pass** `test/js/bun/udp/udp_socket.test.ts` (218), `test/js/bun/udp/dgram.test.ts` (62), `test/js/bun/http/serve-http2.test.ts` (93), `test/js/bun/http/serve-http3.test.ts` (73), `test/bake/dev/bundle.test.ts` (23), `test/bake/dev/esm.test.ts` (17), `test/bake/hmr-socket-protocol.test.ts` (4), `test/cli/inspect/BunFrontendDevServer.test.ts` (7). `test/js/node/dgram/node-dgram.test.js` passes 3 of 4: the IPv6 multicast test fails with `ENODEV` in the test container, with and without this change. `prettier` and `cargo fmt --check` report no change. **Overlap with open pull requests** Each removed line was compared with the diffs of the 35 open dead-code pull requests. None removes the same lines. Five files are also touched by an open pull request, in hunks more than 6 lines away: `internal.h` and `quic.c` (#40294, #42431), `dgram.ts` (#42431), `overlay.ts` (#43378, #42075, #39488), `src/uws_sys/lib.rs` (#43010). The added lines of the 122 open pull requests that were updated since 2026-09-18 and touch the bake, uSockets, uWS, uws_sys, server, socket or CI sources name none of the removed symbols. **What was scanned** - C and C++: the debug binary was linked a second time with `--gc-sections`, and the two symbol tables were compared. 414 functions in bun's own C and C++ are unreachable on Linux. Open pull requests remove 263 of them. The remainder is in the list below, has a caller on Windows or macOS, or comes from a macro. - Rust: 37 `#[no_mangle]` exports are unreachable in the Linux link. Each has a caller on another platform, or #40824, #40232 or #40557 removes it. A count of references for all 58,055 Rust definitions found no other item without a user. Of the 144 `allow` attributes for the unused and unreachable lints, each covers code that depends on `cfg` or is macro output. - Cargo: five dependency edges are unused on all 12 targets. #40294 removes three. `bun_resolver -> bun_zstd` is used under `cfg(bun_codegen_embed)`. `bun_wyhash -> bstr` is used by unit tests. - Preprocessor: `USE(BIGINT32)` and `ENABLE(MALLOC_BREAKDOWN)` are never true. #43644 and #40557 remove those branches. - Also scanned and clean: `src/js`, `src/node-fallbacks`, `src/codegen`, `scripts/`, `misctools/`, `patches/` (every patch file has a user), `packages/` except `bun-types`. **Probably dead, left alone on purpose** - The `PerformanceResourceTiming` cluster under `src/jsc/bindings/webcore` (about 2,000 lines: `PerformanceResourceTiming`, `PerformanceServerTiming`, `ResourceTiming`, `NetworkLoadMetrics`, `ResourceLoadTiming`, `ServerTiming` and the two JS wrappers). The linker drops every constructor, so no instance can exist. The two globals are public and `test/js/web/web-globals.test.js` checks them. This needs a decision: keep it for a future resource-timing implementation, or reduce it to the two constructors. - `WEBCORE_GENERATED_CONSTRUCTOR_GETTER` (`ZigGlobalObject.cpp`) emits an `X_getter` function for 50 classes. 45 have no user. A removal needs a second macro and saves no source lines. - The WebIDL converters for `byte`, `short` and `long long`, and most `Clamp` and `EnforceRange` specializations in `JSDOMConvertNumbers.cpp`. No binding uses them, but `src/codegen/bindgen.ts` maps `t.i8`, `t.i16` and `t.i64` to them. - `src/js/bun/sql.ts`: the export properties `sql`, `Query`, `postgres` and the four error classes. Native code reads only `default` and `SQL`. It is not certain that no loader path exposes the module object. - `us_nq_settings_set_scid_len` and `us_nq_settings_set_delay_onclose` (`node_quic_shim.c`, declared in `src/lsquic_sys/lib.rs`): no caller. `node:quic` is under active work. - `Event::currentTargetIsInShadowTree()` and its bit: no reader. The lines sit next to a hunk of #39929. - Bake client: `WebSocketWrapper.close()` and `[Symbol.dispose]()`, `streamingStarted`, the `line` and `column` bookkeeping and seven enum members in `JavaScriptSyntaxHighlighter.ts`, and `externals` in `src/node-fallbacks/build-fallbacks.ts`. Each sits next to a hunk of #43378, #40492, #40122 or #41385. - The `internal: true` property option of the class generator. A guard throws on it, so the branches behind it cannot run. Five open pull requests touch `generate-classes.ts`. - `H2App::getNativeHandle` (next to a hunk of #41195) and `uws_app_listen_config_t` (its last user goes with #42431). - `UWS_ALLOW_SHARED_AND_DEDICATED_COMPRESSOR_MIX`, `UWS_ALLOW_8_WINDOW_BITS` and `LIBUS_NO_SSL`: never defined, but they are documented opt-in switches of the upstream libraries. - `scripts/debug-coredump.ts`, `scripts/gamble.ts`, `scripts/github-metrics.ts`, `scripts/lldb-inline.sh` with `scripts/lldb-inline-tool.cpp`, and `packages/h3blast`: nothing references them. They read as tools that a person runs by hand. - #40232 removes `napi_internal_get_version`. #42556 renamed that function to `Bun__napi_get_version` on main, and it still has no caller. </details>
…ent.cpp (#45764) ### Problem - 29 lines in 6 files have no user. - `source_file`, `compare_types` and `symbol_to_string` in the `queries!` list of `src/lint/types/mod.rs` have no caller. The list generates the only call of the `Services` functions of the same names in `bun_sema`. The trait is `pub`, so rustc does not check it. - `BunProcess.cpp` declares five `using X = JSC::X;` aliases that it never names. `DirEntType` in `NodeDirent.cpp` has three enumerators that nothing names. ### Fix - Delete the three list lines with their `Services` functions (21 lines), the five aliases and the three enumerators. - Correct because a word search over the sources, the tests and the generated code finds no user, and the workspace compiles for 12 targets. - Verified: `bun bd`, `bun run rust:check-all`, `cargo check --workspace --all-targets`, 8 test files (Notes). - Self-reviewed: 41 concerns raised, 33 addressed. Rejected: a `pub(crate)` narrowing of `Queries` (`resolve_name` needs a caller first), and a hold until earlier sweeps merge. ### Background - `queries!` lists each question that a lint handle (`Type`, `TsSymbol`) can ask the type checker. One line generates a `Queries` method and a forwarding call to `Services` in `bun_sema`. - `BunProcess.cpp` compiles as its own unit with `using namespace JSC;`, so the aliases change no name lookup. - A deletion of unreferenced code has one possible place, so no other design was weighed. ### Downsides - A later lint handle that needs one of the three queries must restore it. - None found for users. Checked: the heads of all 5,559 open pull requests, 12 targets, the tests in Notes. Behaviour change: none <details><summary>Notes</summary> **Removed** - `src/lint/types/mod.rs`: the `queries!` lines `source_file`, `compare_types` and `symbol_to_string`. No call of these names has a `Queries` receiver. The calls that exist go to other functions: `Checker::compare_types` and `Checker::symbol_to_string` in `bun_sema`, a private `compare_types` in `prefer_optional_chain.rs`, and the parser's `source_file`. With `Queries` made crate-private in a scratch edit, rustc reports `resolve_name` as the only query left that is never used. - `src/sema/check/services.rs`, `services/types.rs`, `services/symbols.rs`: `Services::source_file`, `Services::compare_types`, `Services::symbol_to_string`. The generated forwarding call was the only user. What they call (`Files::by_path`, `Checker::compare_types`, `Checker::symbol_to_string`, `Checker::prop_to_string`) keeps other callers. - `src/jsc/bindings/BunProcess.cpp`: the aliases `Exception`, `JSModuleLoader`, `JSModuleRecord`, `SourceOrigin`, `JSNonFinalObject`. None of the names appears in the rest of the file. The same block in `Path.cpp` and `ZigGlobalObject.cpp` is left to #43378 and #42431. - `src/jsc/bindings/NodeDirent.cpp`: the enumerators `Whiteout`, `Door` and `EventPort` of `DirEntType`, all equal to `Unknown`. No C or C++ file names them. **Open pull requests** - Compared at 2026-10-17 16:40 UTC on main 017b243 with the heads of all 5,559 open pull requests, drafts and every author included. - 156 of them touch a file of this diff (151 touch `BunProcess.cpp`). A trial merge of each with main and with this branch (`git merge-tree`) shows that the branch adds a conflict to none. - None deletes one of these lines. None adds a use of a removed name: the added lines were searched for the three query names, the five alias names in `BunProcess.cpp`, and the three enumerators. **Found dead in this run, and left alone** - Already gone on main: three lines in `JSSQLStatement.cpp` and `NodeSqlite.cpp` (#45304). - Another open pull request deletes or rewrites them: 13 commented-out lines in uSockets, uWS, `JSEventTargetCustom.cpp` and `src/node-fallbacks/url.js` (#45709, and #43730 for `url.js`), two typedefs in `InspectorHTTPServerAgent.cpp` (#45725), the `BUN_WEBKIT_VERSION` fallback in `BunProcess.cpp` (#41729), a commented-out line in `src/js/internal/html.ts` (#45682). - An open pull request uses them: `Event::currentTargetIsInShadowTree()` and the `MediaTime` overload of `JSConverter<IDLUnrestrictedDouble>` (#45415). - Held by an earlier sweep for a reason that still holds: the QUIC setters `scid_len` and `delay_onclose` (#43976, and #40220 changes the line above them). - `resolve_name`, the fourth query with no caller. tsgolint's `prefer-readonly` calls `ResolveName` and Bun's port does not, which gives a wrong autofix for a global enum. The fix is handed off and needs the query. After it, `Queries` can become `pub(crate)`, and rustc then guards the list. - Mirrors of typescript-eslint and tsgolint: the write-only fields `ThenCall::on_fulfilled`, `FinallyCall::on_finally`, `BaseTypeOfClassMember::base_type` and `heritage_token`, `TargetElement::is_shorthand`, with `TsNode::token` (as #45402 held them). Also 33 functions from macro lists in `src/lint/types/` that nothing calls, and `File::expr_tags_in_tree`. - Debugging aids: 25 hand-written `Debug` impls in `bun_lint`, 5 in `bun_format`, and `Display` for `Difference`, `FilePoll` and `Part`. - Handed off: the plugin `target` value that nothing reads (`BundlerPlugin::target`, three more members, a parameter of `JSBundlerPlugin__create`, and the Rust enum). Its removal changes an FFI signature. - Needs a decision: `PerformanceResourceTiming` cannot be constructed, so `ResourceTiming.cpp`, `NetworkLoadMetrics.cpp` and `ServerTiming.h` are reachable only from its getters. **How the candidates were found** - Ten text searches, one for each area: `src/js`, the C++ bindings (three parts), uSockets and uWS, the build scripts, the side packages, the three new crates, and commented-out code. - A relink of the debug build with `-Wl,--gc-sections`, with each dropped function mapped to its source line by `llvm-nm -l`: 517 C++ functions and 607 Rust function lines. Almost all are Windows or macOS code, release-only code, or are deleted by an open pull request. - For `bun_sema`: `pub` narrowed to `pub(crate)` on each item that no other crate names, in a scratch tree. rustc reported nothing new. - For 39 trait impls that the linker drops: delete all, compile for linux, windows and darwin and with `--all-targets`, put back each impl that an error names. What stayed deleted is a debugging aid. **Tests, debug build of this branch** (with `--timeout 600000`, because the lint and check tests need more than the default with a debug build) - `test/cli/lint/conformance.test.ts`: 3 pass. - `test/cli/lint/rules.test.ts`: 16 pass. - `test/cli/lint/native-rules.test.ts`: 166 pass. - `test/cli/lint/bun-rules.test.ts`: 100 pass. - `test/cli/check/check.test.ts`: 599 pass, 42 skip. - `test/js/node/process/process.test.js`: 188 pass, 5 skip. - `test/js/node/fs/dir.test.ts`: 23 pass. - `test/regression/issue/24129.test.ts`: 2 pass. </details> <!-- robobun:evidence:begin --> --- **no test proof** · iteration 0 · the description declares no behaviour change, so there is no failing test to prove; the existing suite in CI is the check <!-- robobun:evidence:end -->
Problem
JSC_DECLARE_HOST_FUNCTIONlines inJSBuffer.cppdeclare functions at global scope, but the definitions are innamespace WebCore, so the declared functions do not exist. Example: the class generator emits a<Type>__ptrOffsetconstant for all 94 classes, and nothing reads it.-Wunused-functionand the--gc-sectionslink do not report them. They are prototypes without a definition, generator output, inline header members, type declarations, or write-only fields.Fix
src/,packages/,scripts/,test/andbuild/debug/codegen/outside its own definition. A clang AST pass over all 670 Bun translation units finds no reference to the removed C++ functions, template instantiations included.ZigGeneratedClasses.{h,cpp}1322,JSSink.{h,cpp}99, zero added.WebCoreJSBuiltins.*is byte-identical.bun bd,tsc(no new error),test/internal/source-lints(173 pass), and the suites in the Notes.Background
JSC_DECLARE_HOST_FUNCTION(name)expands to a function prototype in the current namespace. A prototype that nothing defines or calls has no effect.generate-classes.tsandgenerate-jssink.tswrite the C++ wrapper classes for the native types in*.classes.ts. A symbol they emit is dead when no C++, Rust or generated file names it.Notes
Class and sink generators (
src/codegen)generate-classes.ts:extern "C" const size_t <Type>__ptrOffsetand theoffsetOfWrapped()member that only initialized it.rg ptrOffsethits only the generator.generate-classes.ts:<Type>__createWithInitialValuesand<Type>__createWithValuesAndInitialValues(emitted only forShellInterpreter). No Rust or C++ file declares them. Thecreate(vm, global, structure, ctx, values...)overload and its constructor had no other caller.ShellBindings.cppuses the overload that also takesjsvalueArray, which stays.<Type>__createWithValuesstays (Rust calls it).generate-classes.ts: theonStructuredCloneTransferRust thunk. No C++ declares or calls__onStructuredCloneTransfer, and no type hason_structured_clone_transfer.generate-classes.ts:rustModuleResolver.resolveFile(never called).generate-jssink.ts: theJSSink_isSinkdeclaration (no definition, no caller),createPrototypeof the sink classes (prototypes come fromcreateJSSinkPrototype, the controllercreatePrototypestays), theSinkID Sinkconstants of the constructor and controller classes (onlyJS<Name>Sink::Sinkis read), the#if ENABLE(MEDIA_SOURCE)includes ofBufferMediaSource.handJSMediaSource.h(no such headers exist), and six commented-out lines from 2022 to 2024.bundle-modules.ts:#define BUN_NATIVE_MODULE_START_INDEX(no reader, a comment inInternalModuleRegistry.cppnow names the real bound) and two.replace()calls for__debug_end__/__assert_end__, which nothing emits.bake-codegen.ts:bake_empty_file, written for a dependency edge of the removed CMake build.cppbind.ts: the write-only fieldsisManyandisNonNulland the code that computed them.[[ZIG_NONNULL]]is still accepted.bundle-functions.ts:const useThis = trueand its unreachable arrow-function arm, and the"export type"comparison that the tokenizer regex can never produce. The emitted text is identical.C++
JSBuffer.cpp: 66JSC_DECLARE_HOST_FUNCTION(jsBuffer...)lines. They declare::jsBufferPrototypeFunction_*. The definitions and the hash table areWebCore::jsBufferPrototypeFunction_*, defined before their first use.WebSocket.cpp:static String hostName(const URL&, bool).EventEmitter.h:hasEventListeners()andhasEventListeners(VM&, ASCIILiteral).EventTarget.h:hasEventListeners(). Every caller passes anIdentifierorAtomString.JSDOMExceptionHandling.h: theJSGlobalObject*overload ofinvokeFunctorPropagatingExceptionIfNecessary. All 13 callers pass a reference. A pointer argument does not convert to the remaining overload, so a missed caller fails to compile.JSDOMWrapper.h:offsetOfWrapped().Path.cpp,ZigSourceProvider.cpp: four unusedusingaliases.Built-in TS
src/js/private.d.ts:LoaderEntry,LoaderModule(the JS module loader they describe is gone, the one type use inCommonJS.tsbecomesany).src/js/builtins.d.ts:UnderlyingSourceaugmentation,JSCSourceCodeObject.src/runtime/bake/bake.private.d.ts:FileIndex,Config.roots,CommonJSModule. The Rust side writes norootskey.client/websocket.ts: write-onlymainWebSocket(its reader left in Remove dead code from bun-uws, the native BufferList class, built-in JS, the bake dev server assets, the shell, and the SQL crates #40066). Remove dead code from the JSC bindings, the codegen scripts, the CI scripts, bun_core, and bun_jsc #40492 listed it next to theclose()teardown API and kept both. Only the variable goes here,close()andSymbol.disposestay.client/overlay.ts: write-onlyRuntimeError.remapped.hmr-runtime-server.ts:RequestContext.renderAbort.packages and scripts
packages/bun-error/bun-error.css: rules for#BunError-SourceLine-text-highlightExpression,.BunError-Indented,.BunError-divet,.BunError-error-muted. No file emits these names.index.tsx: thehighlightColumnEndprop (forwarded, never read) andlet _i.packages/bun-debug-adapter-protocol:FramerState,state,pendingLength,sizeBuffer,sizeBufferIndexinnode-socket-framer.ts(the parser is position-based), and theextraTsparameter that no caller passes.packages/bun-native-plugin-rs/headers/.../bundler_plugin.h: a stale committed copy (it lacksBUN_LOADER_HTML,YAML,XML).copy_headers.tsrunsrm -rf headersand copies it again before bindgen, so nothing reads the committed file.headers/is now in that package's.gitignore.scripts/build:ConfigureResult.ninjaFile(never read), thezigcolor override intty.ts(no stream has that name), the<cache>/cargoentry inclean.ts(nothing writes that directory).Tests run with the debug build
test/internal/source-lints/(173 pass),test/js/node/buffer-concat.test.ts,test/js/node/buffer-jit.test.ts(11 pass, the differential fuzzer test passes its 120 s limit under ASAN in this container and runs in 1.8 s with a release build),test/js/node/events/event-emitter.test.ts,test/js/bun/shell/bunshell-instance.test.ts,test/js/bun/shell/exec.test.ts,test/js/web/websocket/websocket-blob.test.ts,test/js/web/websocket/error-event.test.ts,test/js/web/url/url.test.ts,test/js/web/abort/abort.test.ts,test/js/web/broadcastchannel/broadcast-channel.test.ts,test/bake/dev/esm.test.ts,test/bake/dev/hot.test.ts,test/js/bun/util/arraybuffersink.test.ts,test/js/bun/util/filesink.test.ts,test/js/web/workers/structured-clone.test.ts,test/js/web/structured-clone-blob-file.test.ts,test/js/bun/runtime-error.test.ts,test/js/node/module/node-module-module.test.js.No test is added. The change only deletes code that nothing references, so there is no behavior to assert. No Rust code changes (one comment), so
rust:check-allhas nothing to check.How the candidates were found
scripts/,packages/,src/codegenandsrc/js.Found, not deleted here
hasExportStarinsrc/runtime/bake/hmr-module.ts: its only call site is a commented-out block from 2025-03. Remove dead code from the JSC bindings, the codegen scripts, the CI scripts, bun_core, and bun_jsc #40492 already left it because the comment says the check is disabled, not dropped, and dev server: register a client component without evaluating it #42934 works in the same file.LIBUS_USE_WOLFSSLinclude arm ofpackages/bun-usockets/src/crypto/openssl.c: nothing defines the macro, but Remove dead code from bun-uws, bun-usockets, the require.extensions FFI, and unused Cargo dependencies #40294 left the uSockets configuration toggles alone on purpose.rustLinkFlags()inscripts/build/rust.ts: no caller, but a comment inbun.tskeeps it as the documented fallback.logsandbaselinebuild options: nothing readscfg.logsorcfg.baselineexcept the banner. Their removal changes the build CLI (bun run build:logs), and tests passbaseline.scripts/build/ci.ts(about 235 lines) and thecpp-only/rust-only/link-onlymodes: ci: build C++, Rust and link in one build-bun step instead of build-cpp + build-bun #37733 left them for a follow-up decision..buildkite/ci.mjs: the never-setdryRun,features,baselinefields and the constantmodeparameter. CI config, not testable here.internal: trueproperty option (guarded by a throw), the d.tsStaticsbranch, therustABI and thereactionshape ingenerate-host-exports.ts(its last user left in Bun.ModuleGraph: a context per graph for timers and I/O, per-graph CommonJS #42590),emitKeys/emitCaseInsensitive/emitIndexOfingenerate-string-map.ts, thefalse_is_throwtag incppbind.ts,$alwaysInline,$isPromiseFulfilled,$isPromiseRejected. They are dead for the current inputs only.<Ctor>::callbody that the class generator emits forcall: trueclasses: Remove dead code from bun_jsc, bun_core, the bindgenv2 codegen, 15 error types, and the C++ bindings #40915 edits the same logic.ERR_REDIS_INVALID_DATABASE,ERR_CRYPTO_INCOMPATIBLE_KEY,ERR_TLS_PROTOCOL_VERSION_CONFLICTinErrorCode.ts: no user. The first is next to hunks of Remove dead code from bun_css, bun_react_compiler, bun_jsc, and smaller crates #40690 and Remove dead code from bun_core, the JSC bindings, the debugger, and 24 other crates #41385. The other two are Node codes that Node's own tests expect.packages/bun-uws: the client-mode (isServer == false) branches ofWebSocketProtocol.h, the default-upgrade arm ofTemplatedApp::ws,maxLifetime(always 0) andresetIdleTimeoutOnSend(always true). They are constant only because of what the Rust side passes today.packages/bun-error/index.tsx:isClientis always true, soblobFileURL/maybeBlobFileURLand the!fallbackStyleSheetbranches cannot run. It needs a read of the dev error page, not a grep.H2App::getNativeHandle()and theexternalsblock insrc/node-fallbacks/build-fallbacks.ts: dead, but each is next to a line that an open PR deletes (Remove dead code from bun-uws, bun-usockets, the require.extensions FFI, and unused Cargo dependencies #40294 / Remove dead code from the WebCore IDL converters, exception reporting, and the uws HTTP/2 shim #41195 and Remove dead code from bun_core, the JSC bindings, the debugger, and 24 other crates #41385).HTTPHeaderMap::indexOf(StringView): declared, never defined. It is next to a line that Remove dead code from the WebCore bindings, the JSSink codegen, and two Rust helpers #39929 deletes.DataViewReader.u16,DataViewWriter.u8,BunBuiltinNames::publicName,ExternColumnIdentifier::isIndexedColumn, const or non-const accessor twins inAbortSignal.h,ResourceTiming.h,EventTarget.h, and several constructors inncrypto.h.src/js/node/tty.ts:this.$bunNativePtris never set on atty.ReadStream, so theref/unrefbranches and$startcannot run. It looks like a WindowssetRawModeregression, not dead code.Clean, so the next run can skip it
#[no_mangle]export, ahost_fn, or macro output.HTTP_HEADERS_EACH_NAME, builtin names,*_getter), IDL converter specializations, and constructors.src/js: no function with zero mentions, no module without a loader, everybun:internal-for-testingexport has a test. No unused selector insrc/runtime/bake/client/overlay.css(thelog-*classes are built by concatenation).src/symbols.txtmatches the binary. No.zigfile and no CMake reference is left outside comments. Commented-out code older than 6 months: 80 lines in total, most inbun-typesdoc examples.