Skip to content

Remove dead code from the JSC bindings, headers.h, the console builtin, and bun_jsc - #40232

Open
robobun wants to merge 5 commits into
mainfrom
claude/farm/5ba7041e/dead-code-bindings-cpp-js
Open

robobun wants to merge 5 commits into
mainfrom
claude/farm/5ba7041e/dead-code-bindings-cpp-js

Conversation

@robobun

@robobun robobun commented Aug 23, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • src/jsc/bindings still carries extern "C" glue from the Zig era that no Rust code declares or calls. The legacy headers.h declares 34 of these, 6 of them with no definition anywhere, plus 13 *__fastpath declarations from the removed DOMJIT FFI fast path.
  • Two whole files are dead: src/jsc/headergen/sizegen.cpp (a generator for make sizegen that references undefined names/sizes arrays and is not built) and webcore/JSDOMBindingInternalsBuiltins.cpp (commented out top to bottom, compiled as an empty TU).

Fix

  • Delete the uncalled functions and their declarations. Every symbol was checked against src/, packages/, scripts/, test/, the regenerated build/debug/codegen/, and the undefined and weak symbol tables of the prebuilt WebKit libraries (nm -u), so the five hooks WebKit itself calls stay.
  • Bun__deepEquals<false, false, false, false> was only instantiated through the removed JSC__JSValue__deepEquals, so it gets an explicit instantiation next to the existing one.
  • Also removed: the unused kBindStreamsLazy console method, a commented-out fileURLToPath in node:url, the AbortSignal__Timeout__run export, VM::has_termination_request, two stale commented-out blocks, and the unused bytemuck dependency of bun_paths.
  • The no-iostream-include lint scanned every .cpp under src/ and kept an allowlist for the one file that is not compiled. It now scans the patterns the build expands (scripts/glob-sources.ts, patterns is exported for that) plus the Windows-only sources scripts/build/bun.ts adds by hand.
  • Verified: bun bd links, test/internal/source-lints/, deep-equals.test.ts, abort.test.ts, plugins.test.ts, bun-serve-cookies.test.ts, napi.test.ts, ffi.test.js, and the node crypto DH/keygen tests pass.

Background

  • Rust reaches C++ through explicit extern "C" declarations (often #[link_name = concat!(...)]) or through build/debug/codegen/cpp.rs, which cppbind.ts generates from [[ZIG_EXPORT]] attributes. A C++ extern "C" function with no such reference cannot be called.
  • The prebuilt JavaScriptCore and ICU expect a few Bun symbols (Bun__errorInstance__finalize, Bun__reportUnhandledError, bun_icu_maybe_decompress) and define Bun__analyzeTranspiledModule and Bun__thisThreadHasVM weak. Those are not dead even though no Bun source references them.
Notes

Net -894 lines (30 files, +28 / -922) after the second rebase. The first version of this PR was -1099; #40374 (ZigString to EncodedSlice) landed on main in between and removed 13 of the same functions (JSC__JSObject__{getDirect,putDirect}, ZigString__{to16BitValue,toAtomicValue,toExternalValueWithCallback}, JSC__JSValue__{createRangeError,createTypeError,putRecord,symbolKeyFor}, JSC__JSGlobalObject__{getCachedObject,putCachedObject,createSyntheticModule_}, JSC__JSValue__{createStringArray,hasOwnProperty}) and both Zig_ErrorCode* statics, so this PR no longer carries them.

bindings.cpp functions removed (each was declared in headers.h or not declared at all):
JSC__JSObject__getArrayLength, JSC__JSCell__getObject, JSC__JSCell__toObject, JSC__JSString__toObject, JSC__JSModuleLoader__evaluate, JSC__JSPromise__asValue, JSC__JSPromise__rejectOnNextTickWithHandled, JSC__JSPromise__resolveOnNextTick, JSC__JSInternalPromise__{create,isHandled,rejectAsHandled,rejectAsHandledException,rejectedPromise,result,setHandled,status}, JSC__JSFunction__optimizeSoon, Bun__REPL__formatValue, JSC__JSValue__{createInternalPromise,createRopeString,deepEquals,eqlCell,fastGetDirect_,fastGetOwn,isError,jsNumberFromInt32,jsNumberFromInt64,jsNumberFromUint64,getPropertyValue,dateInstanceFromNullTerminatedString,DateNowISOString}, JSC__VM__{deleteAllCode,externalMemorySize,notifyNeedDebuggerBreak,notifyNeedShellTimeoutCheck,hasTerminationRequest}.

headers.h declarations with no definition: _fromJS, JSC__JSValue__then, JSC__JSValue__toString, JSC__VM__create, Zig__GlobalObject__fetch, Zig__GlobalObject__promiseRejectionTracker, and the 13 FFI__ptr__fastpath / Reader__*__fastpath lines.

Other files: Yarr__RegularExpression__matchedLength, StringBuilder__{appendUtf16,appendQuotedJsonString}, jsFunctionAppendOn{Load,Resolve}Plugin{Node,Browser}, Process_defaultSetter, Bake__getSSRResponseConstructor, bun_ignore_sigpipe, Bun__disableSOLinger (both platforms), Cookie__fromJS (and the JSCookie.h include it needed), Bun__NodeCrypto__createCryptoError, ByteSource::fromBIO, ByteSource::foreign, Bun__JSBigIntStatFSObjectConstructor, Bun__JSStatFSObjectConstructor, JSC__createEmptyObjectWithStructure, JSC__putDirectOffset, napi_set_ref, napi_internal_get_version, highway_json_index (Rust uses highway_json_index_chunk), rescle__setIcon (Rust uses rescle__setWindowsMetadata), the 2022 commented-out visitChildrenImpl in ZigGlobalObject.cpp, commented-out includes in PerformanceTiming.cpp, and a Zig-syntax comment block in PackageInstaller.rs.

Rebase notes. First rebase (onto bc713f9): #40238 changed BunString parameters to const BunString* next to lines this PR deletes in headers.h, RegularExpression.cpp, StringBuilderBinding.cpp, and BunProcess.cpp; main's signatures were kept, the dead lines dropped. Second rebase (onto 7ca1236): #40374 rewrote the ZigString declarations in headers.h and bindings.cpp as EncodedSlice and removed the 13 functions listed above, so both files were resolved by re-applying this PR's remaining deletions to main's version of each file. Every remaining symbol was re-checked against main for callers before deletion.

Method: identifier-count scans over the whole corpus for extern "C" definitions, JSC_DEFINE_* host functions, out-of-class method definitions, and header declarations; orphan checks for .rs (mod tree), .cpp (compile_commands.json), and src/js (module registry); a cargo check pass per crate with pub downgraded to pub(crate) for names that have no external reference; and a Cargo dependency usage scan. Rust is already built with dead_code = deny and unreachable_pub = deny, so the Rust side is close to clean. The write-only struct fields the compiler pass reported are all column accessors generated by the MultiArrayList macros or RAII owners, and were left alone.

Left out on purpose: src/runtime/api/bun/h2/* carries file-level #![allow(dead_code)] and has unused methods and constants (send_push_promise, MAX_STREAM_ID, ...), but it is under active development. ConsoleObject::recordEnd is a JSC::ConsoleClient override. bun_icu_maybe_decompress is called by the patched ICU inside WebKit.

The FFI test ptr argument: ArrayBuffer cells through an FTL-compiled call site and URL.canParse repeatedly called exceed the 5 s default under this debug build on a slow container (12 s and 7 s); both produce the expected output when given time and do not touch removed code.


[review] gate passed · iteration 2 · 32 files touched

fails on main (without fix)
ASAN without fix: BUILD FAILED (no junit output)
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/no-iostream-include.test.ts
ninja: Entering directory `/workspace/bun/build/debug'
[1/95] gen generated_host_exports.rs
generated_host_exports.rs: 116 exports (host=5, lazy=10, generic=101, rust=0); 242 extern-C blocks audited
[2/95] gen cpp.rs (cppbind)
[3/95] gen BunProcess.lut.h
Generating /workspace/bun/build/debug/codegen/BunProcess.lut.h from /workspace/bun/src/jsc/bindings/BunProcess.cpp
[4/95] gen JS modules (bundle-modules)
Preprocess modules (7804ms)
Bundle modules (114ms)
Postprocesss modules (38ms)
Bundle Functions (469ms)
Generate Code (25ms)

[8.46s] Bundled "src/js" for development
  2786 kb
  197 internal modules
  13 native modules
  50 internal functions across 16 files
[4/93] cargo bun_runtime → libbun_runtime.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19)

[88/93] cc obj/codegen/InternalModuleRegistryConstants.S.o
FAILED: rust-target/x86_64-unknown-linux-gnu/debug/libbun_runtime.a 
/workspace/bu
... (truncated)

release without fix: all passed
bun test v1.4.1-canary.1 (38b08c568)

test/internal/source-lints/no-iostream-include.test.ts:
(pass) C++ sources compiled into Bun do not include <iostream> [77.89ms]

 1 pass
 0 fail
 5 expect() calls
Ran 1 test across 1 file. [167.00ms]
__F:0:S:0
passes on PR (with fix)
ASAN with fix: all passed
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/no-iostream-include.test.ts
bun test v1.4.1 (861e9ae04)

test/internal/source-lints/no-iostream-include.test.ts:
(pass) C++ sources compiled into Bun do not include <iostream> [821.33ms]

 1 pass
 0 fail
 5 expect() calls
Ran 1 test across 1 file. [3.01s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 708ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/63] gen generated_host_exports.rs
generated_host_exports.rs: 120 exports (host=5, lazy=10, generic=105, rust=0); 242 extern-C blocks audited
[2/63] gen cpp.rs (cppbind)
[3/63] gen BunProcess.lut.h
Generating /workspace/bun/build/release/codegen/BunProcess.lut.h from /workspace/bun/src/jsc/bindings/BunProcess.cpp
[4/63] gen JS modules (bundle-modules)
Preprocess modules (7660ms)
Bundle modules (87ms)
Postprocesss modules (46ms)
Bundle Functions (451ms)
Generate Code (57ms)

[8.31s] Bundled "src/js" for production
  2593 kb
  197 internal modules
  13 native modules
  50 internal functions across 16 files
[4/59] cargo bun_runtime → libbun_runtime.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19)

�[1m�[92m   Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/src/ptr)
�[1m�[92m   Compiling�[0m bun_base64 v0.0.0 (/workspace/bun/src/base64)
�[1m�[92m   Compiling�[0m bun_collections v0.0.0 (/workspace/bun/src/collections)
�
... (truncated)
diff hotspot
Cargo.lock                                         |   1 -
 scripts/glob-sources.ts                            |   2 +-
 src/install/PackageInstaller.rs                    |  10 -
 src/js/builtins/ConsoleObject.ts                   |  36 --
 src/js/node/url.ts                                 |  24 --
 src/jsc/AbortSignal.rs                             |  11 +-
 src/jsc/StringBuilder.rs                           |   4 +-
 src/jsc/VM.rs                                      |   9 -
 src/jsc/bindings/BakeAdditionsToGlobalObject.cpp   |   6 -
 src/jsc/bindings/BunPlugin.cpp                     |  20 -
 src/jsc/bindings/BunProcess.cpp                    |  11 -
 src/jsc/bindings/Cookie.cpp                        |   6 -
 src/jsc/bindings/NodeFSStatFSBinding.cpp           |  10 -
 src/jsc/bindings/RegularExpression.cpp             |   4 -
 src/jsc/bindings/SQLClient.cpp                     |  15 -
 src/jsc/bindings/StringBuilderBinding.cpp          |  11 -
 src/jsc/bindings/ZigGlobalObject.cpp               |  31 --
 src/jsc/bindings/bindings.cpp                      | 402 +--------------------
 src/jsc/bindings/c-bindings.cpp                    |  27 --
 src/jsc/bindings/headers.h                         |  50 ---
 src/jsc/bindings/highway_json.cpp                  |  12 -
 src/jsc/bindings/napi.cpp                          |  16 -
 src/jsc/bindings/node/crypto/CryptoUtil.cpp        |  20 -
 src/jsc/bindings/node/crypto/CryptoUtil.h          |   4 -
 .../webcore/JSDOMBindingInternalsBuiltins.cpp      |  78 ----
 src/jsc/bindings/webcore/PerformanceTiming.cpp     |   8 -
 src/jsc/bindings/windows/rescle-binding.cpp        |  12 -
 src/jsc/headergen/sizegen.cpp                      |  87 -----
 src/paths/Cargo.toml                               |   1 -
 src/runtime/ffi/FFI.h                              |   2 +-
 .../source-lints/no-iostream-include.test.ts       |  34 +-
 test/js/bun/ffi/ffi.test.fixture.receiver.c        |   2 +-
 32 files changed, 31 inse
... (truncated)

gate history · 7 passed · 1 rejected · iteration 2

evidence per changed file
file                                              reads  edits  tests
Cargo.lock                                            0      0      0
scripts/glob-sources.ts                               0      0      0
src/install/PackageInstaller.rs                       0      0      0
src/js/builtins/ConsoleObject.ts                      0      0      0
src/js/node/url.ts                                    0      0      0
src/jsc/AbortSignal.rs                                1      1      0
src/jsc/StringBuilder.rs                              0      0      0
src/jsc/VM.rs                                         0      0      0
src/jsc/bindings/BakeAdditionsToGlobalObject.cpp      0      0      0
src/jsc/bindings/BunPlugin.cpp                        0      0      0
src/jsc/bindings/BunProcess.cpp                       0      0      0
src/jsc/bindings/Cookie.cpp                           0      0      0
src/jsc/bindings/NodeFSStatFSBinding.cpp              0      0      0
src/jsc/bindings/RegularExpression.cpp                0      0      0
src/jsc/bindings/SQLClient.cpp                        0      0      0
src/jsc/bindings/StringBuilderBinding.cpp             0      0      0
(+ 16 more files)

@coderabbitai

coderabbitai Bot commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: eab51f84-145f-434c-9082-3410d871e2a9

📥 Commits

Reviewing files that changed from the base of the PR and between 023e84a and 6ca74bc.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (31)
  • scripts/glob-sources.ts
  • src/install/PackageInstaller.rs
  • src/js/builtins/ConsoleObject.ts
  • src/js/node/url.ts
  • src/jsc/AbortSignal.rs
  • src/jsc/StringBuilder.rs
  • src/jsc/VM.rs
  • src/jsc/bindings/BakeAdditionsToGlobalObject.cpp
  • src/jsc/bindings/BunPlugin.cpp
  • src/jsc/bindings/BunProcess.cpp
  • src/jsc/bindings/Cookie.cpp
  • src/jsc/bindings/NodeFSStatFSBinding.cpp
  • src/jsc/bindings/RegularExpression.cpp
  • src/jsc/bindings/SQLClient.cpp
  • src/jsc/bindings/StringBuilderBinding.cpp
  • src/jsc/bindings/ZigGlobalObject.cpp
  • src/jsc/bindings/bindings.cpp
  • src/jsc/bindings/c-bindings.cpp
  • src/jsc/bindings/headers.h
  • src/jsc/bindings/highway_json.cpp
  • src/jsc/bindings/napi.cpp
  • src/jsc/bindings/node/crypto/CryptoUtil.cpp
  • src/jsc/bindings/node/crypto/CryptoUtil.h
  • src/jsc/bindings/webcore/JSDOMBindingInternalsBuiltins.cpp
  • src/jsc/bindings/webcore/PerformanceTiming.cpp
  • src/jsc/bindings/windows/rescle-binding.cpp
  • src/jsc/headergen/sizegen.cpp
  • src/paths/Cargo.toml
  • src/runtime/ffi/FFI.h
  • test/internal/source-lints/no-iostream-include.test.ts
  • test/js/bun/ffi/ffi.test.fixture.receiver.c
💤 Files with no reviewable changes (24)
  • src/install/PackageInstaller.rs
  • src/jsc/bindings/node/crypto/CryptoUtil.h
  • src/jsc/bindings/BunProcess.cpp
  • src/jsc/bindings/napi.cpp
  • src/jsc/bindings/SQLClient.cpp
  • src/jsc/bindings/node/crypto/CryptoUtil.cpp
  • src/jsc/bindings/highway_json.cpp
  • src/jsc/bindings/ZigGlobalObject.cpp
  • src/jsc/VM.rs
  • src/jsc/bindings/webcore/PerformanceTiming.cpp
  • src/paths/Cargo.toml
  • src/jsc/bindings/webcore/JSDOMBindingInternalsBuiltins.cpp
  • src/jsc/bindings/c-bindings.cpp
  • src/jsc/bindings/StringBuilderBinding.cpp
  • src/jsc/bindings/NodeFSStatFSBinding.cpp
  • src/js/builtins/ConsoleObject.ts
  • src/jsc/bindings/BunPlugin.cpp
  • src/js/node/url.ts
  • src/jsc/bindings/RegularExpression.cpp
  • src/jsc/bindings/Cookie.cpp
  • src/jsc/headergen/sizegen.cpp
  • src/jsc/bindings/windows/rescle-binding.cpp
  • src/jsc/bindings/headers.h
  • src/jsc/bindings/BakeAdditionsToGlobalObject.cpp

Included review availability: Your plan provides up to 5 included reviews per hour; 0 remain after this review.


Walkthrough

The pull request removes obsolete FFI and binding exports, deletes dead code and comments, updates source-lint coverage, removes an unused dependency, and replaces the Windows icon update binding with a broader executable metadata update.

Changes

Binding cleanup and build updates

Layer / File(s) Summary
Source pattern export and lint coverage
scripts/glob-sources.ts, test/internal/source-lints/*, src/runtime/ffi/FFI.h, test/js/bun/ffi/*, src/paths/Cargo.toml, src/jsc/headergen/sizegen.cpp
Exports the build source patterns, narrows iostream scanning to selected sources and headers, updates size-generation comments, removes the size-generation utility, and removes bytemuck.
JSC binding contract reduction
src/jsc/bindings/headers.h
Removes obsolete JSC, VM, FFI, Reader, and global-object declarations while retaining selected slow paths and runtime APIs.
JSC binding implementation cleanup
src/jsc/bindings/bindings.cpp, src/jsc/AbortSignal.rs, src/jsc/StringBuilder.rs, src/jsc/VM.rs
Removes legacy binding implementations, updates JSC__JSObject__putRecord, adds explicit deep-equality instantiation, and removes obsolete Rust FFI methods.
Specialized API and platform binding pruning
src/jsc/bindings/BunPlugin.cpp, src/jsc/bindings/NodeFSStatFSBinding.cpp, src/jsc/bindings/RegularExpression.cpp, src/jsc/bindings/SQLClient.cpp, src/jsc/bindings/highway_json.cpp, src/jsc/bindings/napi.cpp, src/jsc/bindings/node/crypto/*, src/jsc/bindings/BunProcess.cpp, src/jsc/bindings/BakeAdditionsToGlobalObject.cpp
Removes unused plugin, StatFS, regular-expression, SQL, JSON, N-API, crypto, process, and SSR constructor bindings.
Runtime and support-code cleanup
src/install/PackageInstaller.rs, src/js/builtins/ConsoleObject.ts, src/js/node/url.ts, src/jsc/bindings/ZigGlobalObject.cpp, src/jsc/bindings/webcore/PerformanceTiming.cpp
Removes obsolete comments and lazy console binding code, and activates the Performance.h include.
Windows executable metadata update
src/jsc/bindings/windows/rescle-binding.cpp
Replaces rescle__setIcon with rescle__setWindowsMetadata, which applies optional metadata and version fields before one commit and returns operation-specific errors.

Possibly related PRs

Suggested reviewers: jarred-sumner

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: removing dead code from JSC bindings and related components. It is specific and concise enough for repository history.
Description check ✅ Passed The description explains the problem, lists the fixes, provides background, and documents verification steps and test results. It is more detailed than the template but includes all required informati…
Full details: Description check

Explanation

The description explains the problem, lists the fixes, provides background, and documents verification steps and test results. It is more detailed than the template but includes all required information.


Comment @coderabbitai help to get the list of available commands.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beyond the inline nit, I spot-checked ~20 of the removed symbols (the BunPlugin host functions, AbortSignal__Timeout__run, Zig_ErrorCodeJSErrorObject, Bake__getSSRResponseConstructor, napi_set_ref, rescle__setIcon, Bun__disableSOLinger, the SQLClient/StatFS/Cookie/CryptoUtil externs, bytemuck in src/paths) for remaining references in Rust, C++, headers, and build scripts — none found. Also confirmed Bun__deepEquals<false, false, false> in BunObject.cpp resolves to the new explicit <false,false,false,false> instantiation via the defaulted 4th param, and that neither sizegen.cpp nor JSDOMBindingInternalsBuiltins is referenced from CMake or scripts/.

Extended reasoning...

Large dead-code sweep across core JSC bindings (29 files, -1099 lines). Correctness for extern "C" removals is largely proven at link time, which the author verified, and every symbol I sampled had zero remaining references. Deferring only because of scale and the breadth of files touched (bindings.cpp, headers.h, ZigGlobalObject.cpp, CryptoUtil), where a maintainer skim of the removed-symbol list is cheap insurance against anything referenced from an in-flight branch or non-grep-visible path.

Comment thread src/jsc/bindings/StringBuilderBinding.cpp
Comment thread src/jsc/StringBuilder.rs
Comment thread src/jsc/bindings/bindings.cpp Outdated
@robobun

robobun commented Aug 23, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 12:42 AM PT - Aug 25th, 2026

✅ @robobun, your commit 6ca74bc28e4eeba82cd566763d6aa31ff71843c2 passed in Build #105461! 🎉


🧪   To try this PR locally:

bunx bun-pr 40232

That installs a local version of the PR into your bun-40232 executable, so you can run:

bun-40232 --bun

Comment thread src/jsc/bindings/headers.h Outdated
Comment thread test/internal/source-lints/no-iostream-include.test.ts Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this PR again after 42f76e5 and found no issues — the earlier nits (JSC__VM__create declaration, Windows .cpp coverage in the iostream lint, stale __appendUtf16 comment) are all addressed. Given the breadth of the sweep (~1100 lines across 31 files including bindings.cpp, headers.h, napi.cpp, and crypto), a human pass is still worthwhile.

Checked this run:

  • Spot-checked a sample of removed symbols (napi_set_ref, Bun__NodeCrypto__createCryptoError, Zig_ErrorCodeJSErrorObject, rescle__setIcon, Bun__disableSOLinger, Cookie__fromJS, the four jsFunctionAppend*Plugin{Node,Browser} host functions, kBindStreamsLazy) — no remaining references anywhere in the tree.
  • Verified the new explicit Bun__deepEquals<false, false, false, false> instantiation matches the 3-arg call at BunObject.cpp:707 via the defaulted 4th template parameter in headers-handwritten.h:404.
  • The rewritten no-iostream-include lint now scans patterns.cxx.paths plus src/jsc/bindings/windows/*.cpp, and still guards each root against a vacuous pass.
Extended reasoning...

Overview

Pure dead-code removal: ~50 unreferenced extern "C" shims from bindings.cpp, matching headers.h declarations (including 8 with no definition and 13 *__fastpath decls), two whole dead files (sizegen.cpp, JSDOMBindingInternalsBuiltins.cpp), assorted uncalled functions from BunPlugin.cpp/BunProcess.cpp/napi.cpp/SQLClient.cpp/c-bindings.cpp/CryptoUtil.{cpp,h}/highway_json.cpp/rescle-binding.cpp, three unused Rust exports, the kBindStreamsLazy console method, commented-out blocks, and an unused bytemuck dependency. One additive change: an explicit template instantiation for Bun__deepEquals<false,false,false,false> to replace the implicit one lost with JSC__JSValue__deepEquals. The no-iostream-include lint is rewritten to derive its file list from the build's own patterns.cxx instead of a hand-maintained allowlist.

Security risks

None. No new code paths; no user input handling touched. The crypto changes remove two unused ByteSource factory methods and an uncalled extern "C" wrapper — the underlying createCryptoError/throwCryptoError remain.

Level of scrutiny

Medium-high. Each individual deletion is trivial to verify, and the PR description documents a rigorous methodology (identifier-count scan across src/packages/scripts/test + regenerated codegen + nm -u on prebuilt WebKit for weak/undefined symbols). Debug and release builds link and targeted tests pass. But the sweep spans 31 files including core FFI surface (bindings.cpp, headers.h, napi.cpp), so a false positive would manifest as a link error only on a platform/config not exercised locally, or as a missing symbol at dlopen time for napi.

Other factors

All three prior review nits from earlier automated passes were addressed in follow-up commits (8b6654f, 676589b, 42f76e5). The bug-hunting system found nothing this run. I spot-verified several removals against the current tree and confirmed the Bun__deepEquals explicit instantiation is load-bearing (BunObject.cpp:707 uses it via the defaulted 4th template arg). Deferring solely on scale — no specific concern remains.

@Jarred-Sumner

Copy link
Copy Markdown
Collaborator

@robobun fix conflicts

@robobun
robobun force-pushed the claude/farm/5ba7041e/dead-code-bindings-cpp-js branch from 42f76e5 to 3d6b203 Compare August 24, 2026 04:22
@robobun

robobun commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased onto current main (bc713f9) as 3d6b203. Main had moved 8 commits. The conflicts were all in files this PR deletes from:

  • src/jsc/bindings/headers.h: Make bun_core::String own its WTF ref #40238 changed the signatures of JSC__JSString__view and JSC__JSValue__symbolFor next to the JSC__JSString__toObject and JSC__JSValue__symbolKeyFor lines this PR removes. Kept main's signatures, dropped the two dead declarations. Both are still defined only in bindings.cpp on main with no caller.
  • src/jsc/bindings/RegularExpression.cpp, StringBuilderBinding.cpp, BunProcess.cpp: Make bun_core::String own its WTF ref #40238 changed neighbouring BunString parameters to const BunString*. Kept main's versions of the live functions, dropped Yarr__RegularExpression__matchedLength, StringBuilder__appendQuotedJsonString, and Process_defaultSetter as before.
  • src/jsc/ErrorCode.rs: main already removed both Zig_ErrorCode* statics, so this PR no longer touches the file.

Debug build links on the rebased branch. no-iostream-include.test.ts, deep-equals.test.ts, and plugins.test.ts pass. Net is now -1080 lines across 30 files.

@robobun

robobun commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased again onto current main (7ca1236) as 2fcd005. Main had moved 19 commits. #40374 rewrote the ZigString declarations in headers.h and bindings.cpp as EncodedSlice and already removed 13 of the functions this PR deleted (the ZigString__* helpers, JSC__JSObject__{getDirect,putDirect}, JSC__JSValue__{createRangeError,createTypeError,putRecord,symbolKeyFor,createStringArray,hasOwnProperty}, JSC__JSGlobalObject__{getCachedObject,putCachedObject,createSyntheticModule_}). Both files were resolved by re-applying the remaining deletions to main's version, and each remaining symbol was re-checked against main for callers first.

Net is now -894 lines (30 files, +28 / -922). The description is updated to match. Debug build links; no-iostream-include.test.ts, deep-equals.test.ts, plugins.test.ts, and abort.test.ts pass on the rebased branch.

Comment thread test/internal/source-lints/no-iostream-include.test.ts
@alii

alii commented Aug 25, 2026

Copy link
Copy Markdown
Member

@robobun Conflicts

…n, and bun_jsc

Delete extern "C" functions in src/jsc/bindings that nothing calls: 45
functions in bindings.cpp that were declared in the legacy headers.h, and
stray helpers in BunPlugin, BunProcess, BakeAdditionsToGlobalObject,
c-bindings, Cookie, CryptoUtil, NodeFSStatFSBinding, SQLClient,
RegularExpression, StringBuilderBinding, highway_json, napi, and the
Windows rescle binding. Drop the matching headers.h declarations, the
declarations that never had a definition, and the DOMJIT fastpath
declarations left over from the removed FFI fast path.

Remove src/jsc/headergen/sizegen.cpp (a Zig-era generator that no longer
compiles and is not built) and JSDOMBindingInternalsBuiltins.cpp, a file
that is commented out from top to bottom but still compiled as an empty
translation unit.

Remove the kBindStreamsLazy console method, a commented-out
fileURLToPath in node:url, the unused AbortSignal__Timeout__run and
Zig_ErrorCodeJSErrorObject exports, VM::has_termination_request, and the
unused bytemuck dependency of bun_paths.

Bun__deepEquals<false, false, false, false> was instantiated only through
the removed JSC__JSValue__deepEquals wrapper, so it now has an explicit
instantiation next to the existing one.
…stead of an allowlist

The lint scanned every .cpp under src/ and kept an allowlist for the one
file that is not compiled. Glob the patterns the build expands instead,
so the set of translation units it checks is the set the build compiles.
Headers are still scanned under the same roots as before.

Also drop the mention of the removed StringBuilder__appendUtf16 from the
comment in src/jsc/StringBuilder.rs.
alii pushed a commit that referenced this pull request Aug 25, 2026
…sc JSC bindings (#40413)

### Problem
- Four Rust host exports have no C++ caller:
`Bun__WebSocketClient__writeBlob`, `Bun__WebSocketClientTLS__writeBlob`,
`Bun__WebSocketClientTLS__initWithTunnel`, and
`Bun__internal_drainTimers`. `WebSocket.cpp` converts a Blob to bytes
itself and calls `writeBinaryData`, and the tunnel path only creates the
non-TLS client. The `HOST_EXPORT` marker roots each of them, so neither
rustc nor hawk can see that they are dead.
- A handful of C++ methods are declared and defined but never called:
`HTTPParser::lessThan`, one `JSNodePerformanceHooksHistogram::create`
overload, `JSAbortAlgorithm::callbackData` and `toJS(AbortAlgorithm&)`,
`JSPerformance::toWrapped`, `JSCStackFrame::typeName`,
`root(CryptoKey*)`, the `String` overload of `throwNodeRangeError`, and
16 ncrypto helpers.
- Two `pub` Rust items have no caller in any crate:
`bun_base64::simdutf_encode_url_safe_alloc` and
`CowSliceZ::init_unchecked`.

### Fix
- Delete the items above. `WebSocketClient::write_blob` goes with its
exports. `encode_append_impl` folds into `encode_append`, its only
remaining caller. The ncrypto `Ec` class keeps its one live member,
`GetCurveIdFromName`.
- Every deletion is confirmed two ways: `rg` over `src/`,
`build/debug/codegen/`, `src/codegen/`, `packages/`, and `vendor/WebKit`
finds no reference, and a `bun-debug` relink with `--gc-sections
--print-gc-sections` discards each symbol. `host_fn_this_value` and
`root(MessagePort*)` looked the same way and stay: codegen emits the
first, and #39841 is editing `MessagePort.cpp`, so the second waits for
that fix to land.
- New source lint
`test/internal/source-lints/host-export-callers.test.ts`: every
`c`/`jsc` `HOST_EXPORT` marker must be named by a C or C++ source. It
fails on main with exactly the four exports above and passes here.
- Verified: `bun bd` builds, `bun run rust:check-all` passes on all 12
targets, `clang-format` and `cargo fmt` are clean. Ran
`test/js/web/websocket/` (blob, client, bidir proxy),
`test/js/node/crypto/` (crypto, ecdh, hmac, sign, x509), `node-http`,
`node-http-parser`, `perf_hooks`, and `abort`.

### Background
- `// HOST_EXPORT(Name, c)` marks a Rust fn that
`src/codegen/generate-host-exports.ts` wraps in an `extern "C"` thunk
for C++. The thunk exists whether or not C++ calls it, so an orphaned
export compiles without a warning.
- ncrypto (`src/jsc/bindings/ncrypto.{cpp,h}`) is Bun's copy of Node's
OpenSSL helper layer. Node still uses the removed helpers; Bun's callers
never did.
- The linker check: a debug link with `-Wl,--gc-sections
-Wl,--print-gc-sections` lists every function section nothing
references. A function that is discarded and also absent from the linked
binary has no caller on that platform. Platform-gated code then needs a
source check, which is why the darwin-only `Bun__noOrphans_*` and the
Windows-only `windowsEnv` builtin stay.

<details><summary>Notes</summary>

Removed, by file:

- `src/http_jsc/websocket_client.rs`:
`bun__websocketclient__write_blob`,
`bun__websocketclienttls__write_blob`,
`bun__websocketclienttls__init_with_tunnel`,
`WebSocketClient::write_blob`, and the now unused `JSValue` import.
- `src/runtime/timer/Timer.rs`: `drain_timers_export`
(`Bun__internal_drainTimers`).
- `src/base64/lib.rs`: `simdutf_encode_url_safe_alloc`;
`encode_append_impl` folded into `encode_append`.
- `src/ptr/CowSlice.rs`: `CowSliceZ::init_unchecked`.
- `src/jsc/bindings/node/http/NodeHTTPParser.{cpp,h}`:
`HTTPParser::lessThan`.
- `src/jsc/bindings/JSNodePerformanceHooksHistogram.{cpp,h}`:
`create(VM&, Structure*, JSGlobalObject*, HistogramData&&)`.
- `src/jsc/bindings/webcore/JSAbortAlgorithm.{cpp,h}`: `callbackData()`,
`toJS(AbortAlgorithm&)`, `toJS(AbortAlgorithm*)`.
- `src/jsc/bindings/webcore/JSPerformance.{cpp,h}`:
`JSPerformance::toWrapped`.
- `src/jsc/bindings/ErrorStackTrace.{cpp,h}`: `JSCStackFrame::typeName`,
`retrieveTypeName`, `m_typeName`.
- `src/jsc/bindings/webcrypto/CryptoKey.{cpp,h}`: `root(CryptoKey*)` and
the `WebCoreOpaqueRoot` forward declaration and include it needed.
- `src/jsc/bindings/webcore/JSDOMOperation.{cpp,h}`:
`throwNodeRangeError(JSGlobalObject*, ThrowScope&, const String&)`;
every caller passes an `ASCIILiteral`.
- `src/jsc/bindings/ncrypto.{cpp,h}`: `CryptoErrorList::add`,
`CryptoErrorList::pop_front`, `BignumPointer::encode`,
`BignumPointer::encodeInto`, `X509View::clone`, `BIOPointer::New(const
BIO_METHOD*)`, `BIOPointer::Write`, `EVPKeyPointer::bits`,
`Cipher::EMPTY`, `ECKeyPointer::New(const EC_GROUP*)`,
`EVPKeyCtxPointer::derive`, `HMACCtxPointer::digest`, `Ec::Ec()`,
`Ec::Ec(const EC_KEY*)`, `Ec::getGroup`, and the `Ec` conversion
operators and field.

Scan summary for this run. Areas: Rust in `src/runtime`, `src/http_jsc`,
`src/bun_core`, `src/base64`, `src/ptr`, and the JSC bindings outside
the files that open dead-code PRs (#39929, #40232, #40367, #40294,
#40172, #40122) already touch; the TS builtins in `src/js`.

- hawk over `x86_64-unknown-linux-gnu`, `x86_64-pc-windows-msvc`,
`aarch64-apple-darwin` (release profile, per `hawk.toml`): 847
`dead_public` findings. 668 are fields of FFI mirror structs
(`libuv.rs`, `windows_sys/externs.rs`, `boringssl.rs`). Most of the rest
are in files the open PRs own, are debug-only (`has_resolve_breakpoint`,
`StoredTrace::capture`, `ArrayHashMap::unlock_pointers`), are codegen
targets (`host_fn_this_value`), or are FFI enum mirrors
(`tty::Mode::Io`, `ImplementationVisibility`).
- oxlint with `no-unused-vars`, `no-unused-private-class-members`,
`no-unreachable` over `src/js`: 0 findings. No `src/js` file is
unimported. No `.rs` file is outside a `mod` tree except the three
`[[bench]]` targets.
- `--gc-sections` relink of `bun-debug`: 1005 non-generated discarded
symbols, 283 of them in files no open PR touches. After removing
sqlite3.c, llhttp, vendored shims, platform-gated code, and generated
`ZigGeneratedClasses` helpers, the list above is what remains.

Possibly dead, left alone:

- `bun_core::strings::split_once` / `rsplit_once`: no caller today, but
`clippy.toml` names them as the replacement for the denied
`str::split_once` / `bstr::split_once_str` forms. Kept as API surface.

- `src/jsc/bindings/webcore/streams/JSCrossRealmTransformState.{cpp,h}`
(135 lines): the `CrossRealm` source and sink kinds in
`StreamsForward.h` are never constructed. It reads as scaffolding for
stream transfer in the native streams work, so it stays.
- `ECDSASigPointer`, `ECGroupPointer`, `ECPointPointer`,
`HMACCtxPointer`: default constructor, move constructor, and `release()`
are unreferenced, but they are the smart-pointer idiom the rest of
ncrypto follows.
- `src/threading/Futex.rs` `wasm_impl` and `unsupported_impl`: no
shipped target compiles them.
- `bun_core::Global::StoredTrace::{EMPTY, capture}`,
`has_resolve_breakpoint`, `ArrayHashMap::unlock_pointers`,
`TaskTag::name`: release-dead, used under `debug_assertions`.

</details>
@robobun
robobun force-pushed the claude/farm/5ba7041e/dead-code-bindings-cpp-js branch from 92fc926 to 38b08c5 Compare August 25, 2026 06:59
@robobun

robobun commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased onto current main (2f1dd37) as 38b08c5. Main had moved 5 commits. The only conflicts were in bindings.cpp, where #40410 added exception checks inside three functions this PR deletes (JSC__JSModuleLoader__evaluate, JSC__JSValue__fastGetOwn, JSC__JSValue__createRopeString). All three still have no caller on main, so the deletions stand. Net is -904 lines (32 files, +30 / -934). Debug build links; no-iostream-include.test.ts, deep-equals.test.ts, plugins.test.ts, and the ffi print test pass on the rebased branch.

Comment thread src/jsc/AbortSignal.rs
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this PR across four passes and found no bugs; the earlier stale-comment nits (__appendUtf16, JSC__VM__create, make sizegen, create/run/deinit) are all addressed. Because it removes ~900 lines across 32 files in the core JSC bindings (bindings.cpp, headers.h, napi.cpp, ZigGlobalObject.cpp), a maintainer sign-off is still worthwhile.

What was reviewed:

  • Spot-checked ~15 removed symbols (napi_set_ref, Bun__disableSOLinger, jsFunctionAppendOn{Load,Resolve}Plugin{Node,Browser}, JSC__putDirectOffset, rescle__setIcon, highway_json_index, Cookie__fromJS, kBindStreamsLazy, etc.) — none have remaining references in src/, test/, or scripts/.
  • Verified the new explicit Bun__deepEquals<false, false, false, false> instantiation matches BunObject.cpp's use (4th template arg defaults to false); the <true, false, false, false> combination is still instantiated via strictDeepEquals.
  • Confirmed webcore/AbortSignal.cpp declares only __create/__deinit, so removing AbortSignal__Timeout__run and updating the LAYERING comment is consistent.
  • The rewritten no-iostream-include lint covers patterns.cxx plus the hand-added Windows sources; the expect(compiled).toBeGreaterThan(0) and per-root header guards keep it non-vacuous.
Extended reasoning...

Overview

This PR removes ~900 lines of dead code across 32 files: uncalled extern "C" glue in bindings.cpp/headers.h and a dozen other C++ binding files, two whole dead files (sizegen.cpp, JSDOMBindingInternalsBuiltins.cpp), an unused Rust FFI export (AbortSignal__Timeout__run) and method (VM::has_termination_request), the unused kBindStreamsLazy console method, commented-out blocks in url.ts/ZigGlobalObject.cpp/PackageInstaller.rs, and the bytemuck dep from bun_paths. It also rewrites the no-iostream-include lint to scan the build's actual source patterns (dropping the sizegen.cpp allowlist), and adds one explicit template instantiation for Bun__deepEquals<false,false,false,false> to replace the one lost by removing JSC__JSValue__deepEquals.

Security risks

None identified. Pure deletion of unreferenced symbols; no auth, crypto behavior, or input-validation surface changes. The CryptoUtil removals (ByteSource::fromBIO/::foreign, Bun__NodeCrypto__createCryptoError) are unreferenced helpers, not live crypto paths.

Level of scrutiny

High, because the touched files are load-bearing JSC/N-API bindings — but the change class is low-risk: an accidentally-removed live symbol would fail the link, and the evidence shows both debug and release builds link. The one non-deletion logic change (the explicit template instantiation) I verified against BunObject.cpp's call sites and the template's default-argument declaration in headers-handwritten.h. The lint rewrite is well-guarded against vacuous passes.

Other factors

I've already reviewed four iterations of this PR; every prior finding was a documentation-only stale-comment nit and each was fixed. Two maintainers (Jarred-Sumner, alii) have engaged to request rebases but have not yet approved, and the PR has been rebased three times with careful conflict notes. Given the scale (32 files in core bindings) and that maintainers are already in the loop, deferring for a human sign-off rather than auto-approving.

Jarred-Sumner pushed a commit that referenced this pull request Aug 30, 2026
…misc sources (#40881)

### Problem
- The C++ side of the Rust/C++ FFI still defines shims that no Rust code
calls. The Rust side now implements `JSValue::is_int32`, `is_null`,
`is_object`, `js_type`, and friends inline (`src/jsc/JSValue.rs`), but
the `[[ZIG_EXPORT]]` / `CPP_DECL` functions they replaced stayed in
`src/jsc/bindings/bindings.cpp` and `headers.h`, and `cppbind.ts` still
emitted Rust wrappers for them.
- `src/uws_sys/libuwsockets_h2.cpp` defines seven `uws_h2_res_*` C shims
with no Rust declaration, and one (`uws_h2_res_override_write_offset`)
whose only Rust wrapper nothing calls.

### Fix
- Delete 21 functions from `bindings.cpp` and their 15 `headers.h`
declarations: `JSC__JSValue__{isCell, isCustomGetterSetter,
isGetterSetter, isInt32, isInt32AsAnyInt, isNull, isNumber, isObject,
isUndefined, isUndefinedOrNull, jsNumberFromChar, jsNumberFromU16,
jsTDZValue, jsType}`, `JSC__JSMap__has`, `JSC__JSPromise__isHandled`,
`JSC__JSInternalPromise__{reject, resolve}`, `JSC__VM__{isJITEnabled,
isTerminationException, performOpportunisticallyScheduledTasks}`.
- Delete `uws_h2_res_{override_write_offset, get_write_offset,
prepare_for_sendfile, get_native_handle, get_socket_data, uncork,
is_corked}` and `Response::override_write_offset` in
`src/uws_sys/h2.rs`.
- Delete the unused `BREAKING_CHANGES_BUN_1_2` macro in
`JSSQLStatement.cpp`, the unreachable `#else` branches of two `#if 1`
blocks in `CryptoAlgorithmRSA_PSSOpenSSL.cpp`, and the never-exported
`SlowBuffer` in `src/node-fallbacks/buffer.js`.
- Verified: every symbol has zero references in `src/**`, `packages/**`,
`build/debug/codegen/**`, and the prebuilt WebKit libraries. `bun bd`
links, `bun run rust:check-all` passes on all 12 targets. Ran
`serve.test.ts`, `serve-http2.test.ts`, `serve-http2-protocol.test.ts`,
`sqlite.test.js`, `web-crypto.test.ts`, `buffer.test.js`,
`bundler_browser.test.ts`.
- No test: unreferenced code has no observable behavior, and
`test/internal/source-lints/CLAUDE.md` asks for no dead-symbol lint
tests.

### Background
- `[[ZIG_EXPORT(mode)]]` marks a C++ function that
`src/codegen/cppbind.ts` scrapes into `build/*/codegen/cpp.rs` as a Rust
`extern "C"` declaration plus a safe wrapper. Rust calls the wrapper as
`bun_jsc::cpp::Name`. A function with no Rust caller is unreachable: C++
never calls these shims directly.
- `headers.h` carries hand-written `CPP_DECL` prototypes for the same
extern "C" surface. Both sides were trimmed together.
- The prebuilt WebKit libraries reference a few `Bun__*` symbols and
define two weak defaults that Bun overrides (`Bun__thisThreadHasVM`,
`Bun__analyzeTranspiledModule`). None of the deleted symbols is in
either set.

<details><summary>Notes</summary>

How the candidates were found:

- Per crate, every `pub` Rust item with zero textual references outside
its crate was rewritten to `pub(crate)`, then `cargo check -p <crate>`
was run with `dead_code` as a warning, on linux, windows, and darwin
targets. Items flagged on all three targets and not referenced from
macro bodies (`$crate::`) were the Rust candidates. After excluding
files and symbols that the 13 open dead-code PRs already remove, the
only survivor was `Response::override_write_offset`. The workspace
already compiles with `dead_code = "deny"` and `unreachable_pub =
"deny"`, so private dead code cannot exist.
- `nm --defined-only` over every object in `build/debug/obj` and
`libbun_runtime.a`, minus `nm --undefined-only` over all objects and the
WebKit libraries (`libWTF.a`, `libJavaScriptCore.a`, `libbmalloc.a`,
including their weak symbols), gave the set of C-linkage symbols nothing
references at link time. A test link with `--gc-sections
--print-gc-sections` (without `-rdynamic`) confirmed the same set.
Codegen-emitted symbols (`*__fromJS`, `*GetCachedValue`, JSSink
`*__createObject`) were excluded because they are regenerated from
`.classes.ts`.
- Every remaining bun C++ translation unit was also compiled with
`-fsyntax-only -Wunused-function -Wunused-template
-Wunused-member-function`. The 14 warnings were either in files open PRs
already edit or header templates used by other translation units.
- `src/js/**` and `src/node-fallbacks/**` were checked export by export.
`oxlint` already enforces `no-unused-vars` there, and all 235 bundled
files and every `internal/*` export have consumers.

Not touched on purpose:

- `Bun__thisThreadHasVM` looks unreferenced but WebKit's
`RunLoopBun.cpp` declares it weak and asserts in its fallback. Removing
it aborts every run.
- `src/jsc/bindings/webcrypto/*.idl` (29 files) have no consumer, but
the webcore `.idl` files are kept the same way as reference for the
hand-written bindings.
- `src/runtime/webview/ObjCRuntime.{h,cpp}`: `NSObject::describe` and
`WKWebView::isLoading` have no callers, but the file compiles only on
macOS.
- `bindings.cpp` and `headers.h` are also edited by #40232 and #40824.
The deleted functions are disjoint from both, but hunks are adjacent, so
whichever merges second needs a trivial rebase.

</details>
robobun pushed a commit that referenced this pull request Aug 31, 2026
…r::UnexpectedEof

ConsoleObject.ts (kBindStreamsLazy) is removed by #40232, and Channel::close
and BlobExt::transfer by #40557. Leave those to their PRs.

ParseError::UnexpectedEof is never constructed. Remove the variant and the
arm that mapped it. The yaml module doc no longer names a u16 unit.
alii pushed a commit that referenced this pull request Sep 8, 2026
…llections, and three JS builtins (#42069)

### Problem
- 25 dead-code PRs are already open, so a name grep finds little that is
unclaimed. This run used the compiler instead: demote each `pub` item to
`pub(crate)` and let rustc's `dead_code` lint say what nothing uses.
- What survived that check on all nine CI target triples, and is not
already in an open PR, is the list below.

### Fix
- `bun_runtime::Error`: remove 14 variants that nothing constructs
(`FmtError`, `ERR_TLS_CERT_ALTNAME_INVALID`, `ConnectionClosed`,
`MissingCredentials`, `InvalidMethod`, `InvalidEndpoint`,
`InvalidSessionToken`, `SignError`, `MissingPackageJSON`,
`MissingEntryPoint`, `lcovCoverageError`, `CompilationFailed`,
`JSErrorObject`, `Unsupported`), their `name()` arms, the two match arms
that tested for them (`cli/mod.rs`, `jsc_hooks.rs`), and a
`cfg(not(macos))` block inside a `cfg(macos)` function in
`webview/HostProcess.rs`.
- `bun_jsc`: remove `CrateError::JSErrorObject` (its only producer was
the arm above) and the three never-called `HotReloadTaskView` methods.
The trait stays as the type-erasure marker that `HotReloaderCtx::reload`
takes.
- `bun_collections`: `StringHashMap::values_mut` has no caller in any
crate.
- JS builtins: a 23-line commented-out `fileURLToPath` in `node/url.ts`
(unchanged since 2025-01), the unused `format` / `formatWithOptions`
getters in `internal/repl/node-inspect.js`, and the unused
`reportUncaughtException` export in `internal/shared.ts`.
- Verified: `cargo check --workspace` on all nine triples from
`rust:check-all`, `bun bd`, then `repl.test.ts`,
`readline.node.test.ts`, `hot.test.ts`, `watch.test.ts`, and the
`node/url` tests.

### Background
- The workspace denies `dead_code` and `unreachable_pub`, so rustc
already rejects unused private items. The blind spot is a `pub` item
that is reachable from its crate root but that no other crate imports.
Demoting it to `pub(crate)` puts it back under the lint.
- A demoted inherent method can silently lose to a trait method of the
same name in other crates (`Blob::finalize` against the blanket
`JsFinalize`, `__IsFreeze::IS_FREEZE` against `__NotFreeze`). rustc then
reports the inherent item as dead while behavior changed. Every method
hit was checked for a same-named path in other crates and those were
left alone.

<details><summary>Notes</summary>

- Scope: 87 Rust crates (everything under `src/` except the proc-macro
crates), `src/js`, the C++ `extern "C"` definitions in
`src/jsc/bindings`, `Cargo.toml` dependencies, and orphan `.rs` files
(via cargo dep-info). No unused dependencies and no orphan files were
found.
- Found dead but already removed by an open PR, so not repeated here:
the `bindgen.rs` marker structs and `ExportRenamer` (#40915, #40557),
the `uws_sys`/`mimalloc_sys`/`lsquic_sys` externs (#40172),
`has_termination_request`, `clear_exception`, `from_typed_array`,
`INTERNAL_MODULE_REGISTRY_FLAG`, and the 20 orphaned C++ `extern "C"`
functions (#40232).
- Probably dead, left out of the diff: 119 never-constructed `Feature`
variants in `src/css/prefixes.rs` (the file is generated by
`build-prefixes.js`), the never-constructed
`bake::Mode::ProductionDynamic`, and several struct fields rustc reports
as never read that exist to own an allocation (`JSTranspiler::arena`,
`CurrentBundle::{bv2, heap, ast_alloc_state}`).
- rustc's lint misreports inherent associated types
(`ThreadPool::Worker`, `EntryPoint::Kind`) as unused. They are used and
were kept.
- `bun_core::strings::split_once` (the multi-byte variant) has no
caller, but `clippy.toml` names it as the replacement for
`str::split_once` and `bstr`'s `split_once_str`, so it stays.

</details>
Jarred-Sumner pushed a commit that referenced this pull request Sep 15, 2026
…al-field cells, Http2Response, and the WebView ObjC wrappers (#42816)

### Problem
- Four native class members exist only for built-in JS, and nothing
calls them: the SQL connection `connected` getter and `onconnect`
accessor, `NodeHTTPResponse.ended`, and
`crash_handler.getFeaturesAsVLQ`.
- Thirteen `JSInternalFieldObjectImpl` subclasses carry a copied `static
size_t allocationSize(Checked<size_t>)`. Each `create()` uses
`allocateCell<T>(vm)`, which takes `sizeof(T)`. JavaScriptCore calls
`allocationSize` only on its own classes.
- Other leftovers have no reader: two WebCore members, eight
`Http2Response` members and the `socketData` field behind one of them,
two `ObjCRuntime` wrappers, `.typos.toml`, and
`packages/bun-error/img/*`.

### Fix
- Delete each item: 31 files, 154 lines and 4 images removed. The Notes
list every symbol.
- Correct because every removed name has zero references in `src/`,
`packages/`, `scripts/`, `test/` and `build/debug/codegen/` outside its
own definition. No removed member is documented or typed API.
- Verified: `bun bd` and `bun run rust:check-all` (12 targets) pass. The
sql, `node:http`, streams, `serve-http2`, node error-code, performance
and crash-handler test files pass. `ObjCRuntime` compiles only on macOS,
so CI is the compile check for those 13 lines.

### Background
- A `*.classes.ts` file declares the members of a native class. The
generator emits the C++ wrapper and the Rust glue. The generated thunk
is `#[no_mangle]`, so neither rustc nor the linker reports a member that
no JS reads.
- `values: ["onconnect", ...]` in `sql.classes.ts` declares a GC-visited
slot on the wrapper. Native code uses the slot through
`onconnect_get_cached` / `onconnect_set_cached`. The removed accessor
was a JS-facing route to the same slot. The slot stays.
- 34 other dead-code pull requests are open. This one deletes nothing
that they delete. Six files overlap on other lines (listed in the
Notes).

<details><summary>Notes</summary>

No test is added. The change deletes code that has no user, so it has no
behavior to cover, and REVIEW.md says not to add tests that check dead
code stays dead.

Overlap with open pull requests:

- No deleted line is a line that one of the 34 open dead-code pull
requests deletes (checked line by line against their diffs).
- Six files also change in one of them, on other lines:
`scripts/glob-sources.ts` (#40232), `src/jsc/bindings/ErrorCode.h`
(#39929), `JSOneShotDirectSink.h` (#41385),
`JSStreamAlgorithmContexts.h` (#41445),
`src/runtime/api/crash_handler_jsc.rs` (#41385),
`src/sql_jsc/postgres/PostgresSQLConnection.rs` (#40824).
- The diffs of the 227 open pull requests (newest 2,500) that touch the
`node:http`, sql, crash-handler, streams-header, webview or uws HTTP/2
files add no user of a removed name.

Removed, one line each:

- `PostgresSQLConnection.connected` / `MySQLConnection.connected` and
both `get_connected`. Every `.connected` in `src/js/internal/sql/` and
`src/js/bun/sql.ts` is `PooledConnectionState.connected`. `test/js/sql`
mentions it in comments only.
- `PostgresSQLConnection.onconnect` / `MySQLConnection.onconnect`
accessor and the two `(get_on_connect, set_on_connect => ...)` lines of
`cached_prop_hostfns!`. Every JS `onconnect` is on the options object
(`connectionInfo.onconnect`, `ret.onconnect`).
- `NodeHTTPResponse.ended` / `get_ended`. The `_http_*` modules read
`handle.flags & NodeHTTPResponseFlags.ended`. The other `.ended` hits
are `queued.ended`, `_readableState.ended`, and the JS handle in
`http1_server_fallback.ts`.
- `crash_handler.getFeaturesAsVLQ` / `js_get_features_as_vlq`, and the
`BoundedArray` import that only it used. `getFeatureData` and the other
entries have users in `test/`, `scripts/` or `packages/bun-release`.
- `allocationSize` in `InternalModuleRegistry.h`, `ErrorCode.h`
(`ErrorCodeCache`), `BunStreamSource.h`,
`JSAsyncIteratorSourceOperation.h`, `JSDirectStreamSource.h`,
`JSOneShotDirectSink.h`, `JSReadRequest.h` (2),
`JSReadStreamIntoSinkOperation.h`,
`JSReadableStreamIntoArrayOperation.h`, `JSStreamAlgorithmContexts.h`,
`JSStreamTeeState.h`, `JSStreamPipeToOperation.h`. `rg allocationSize
src packages build/debug/codegen` found the 14 definitions and no call.
The debug objects contain no `allocationSize` symbol for a bun class.
The fourteenth copy, in `JSCrossRealmTransformState.h`, stays because
#41445 deletes that file.
- #41268 lists `InternalModuleRegistry::allocationSize` under "Kept on
purpose" because it corrects the base class version, which returns
`sizeof(JSInternalFieldObjectImpl)`. That reason does not hold. Nothing
calls either version for these classes, `allocateCell<T>(vm)` sizes the
cell from `sizeof(T)`, and four other subclasses (`ModuleLoader.h`,
`JSSocketHandlers.h`, `JSNextTickQueue.h`, `JSMockFunction.h`) never had
the copy.
- `JSPerformanceResourceTiming::protectedWrapped`. The callers of
`protectedWrapped()` are on `JSDOMURL`, `JSAbortSignal` and the
`CookieMap` wrapper.
- `ResourceLoadTiming::isolatedCopy`. No caller.
- `Http2Response::getWriteOffset`, `overrideWriteOffset`,
`getSocketData`, `prepareForSendfile`, `uncork`, `isCorked`,
`getNativeHandle`, `isConnectRequest`
(`packages/bun-uws/src/Http2Context.h`), and
`Http2ResponseData::socketData`, which only `getSocketData` read and
nothing wrote. The callers of the last four names in `libuwsockets.cpp`
are on `HttpResponse<SSL>` and `AsyncSocket<SSL>`. `libuwsockets_h2.cpp`
uses none of the eight. #40294 removes the same-named members of
`HttpResponse` and `Http3Response`.
- `ObjCRuntime`: `struct NSObject` (only member: `describe()`),
`Ref::s_description`, `WKWebView::isLoading()`,
`WKWebView::s_isLoading`. Each name has only its declaration, definition
and `sel(...)` initializer.
- `.typos.toml`. Its runner, `.github/workflows/typos.yml`, was deleted
in 126f468 (2025-11-05).
-
`packages/bun-error/img/{close.png,error.png,powered-by.png,powered-by.webp}`,
last touched 2021-09-11. `bun-error.css` uses inline `data:` URIs. The
`img/*` glob in `scripts/glob-sources.ts` goes with them.

Tests run with the debug build:
`test/js/sql/sql-onconnect-onclose-throw.test.ts` (9),
`sql-connection-socket-uaf.test.ts` (2),
`sql-mysql-clean-reentry.test.ts` (1), `sql-mysql.test.ts`,
`sql.test.ts`, `test/js/node/http/node-http.test.ts` (159),
`node-http-uaf.test.ts` (9), `test/js/web/streams/streams.test.js`
(563), `test/js/bun/http/serve-http2.test.ts` (90),
`test/js/web/timers/performance-entries.test.ts`,
`test/cli/run/run-crash-handler.test.ts` (28), `test/js/node/errors/` (2
files), `test/js/bun/util/error-code-mirror.test.ts`.

How the candidates were found:

- A repo-wide identifier index (definitions with zero other mentions,
comments stripped).
- A compiler pass over a scratch copy of the workspace: every `pub` item
that no other crate names becomes `pub(crate)`, then `cargo check
--force-warn dead_code` runs for linux (dev and release), windows and
macos. A loop restores `pub` at each definition that a privacy error
points to. 131 leaf items came out of it.
- A second compiler pass marks each of those 131 items `#[deprecated]`
in an unmodified copy and checks all four configurations again. 88 had a
real user. The first pass misses them because a private inherent method
silently loses method resolution to a trait method of the same name. 43
had none.
- Manual review dropped all 43: unit-test users (`CowSlice::init_dupe`,
`clap::SliceIterator`, `Imports::ALL_SORTED`, the `h2::Connection` send
path), names that `generate-classes.ts` emits (`host_fn_setter`,
`host_fn_this_value`), a FreeBSD-only user (`O::EVTONLY`), the
`__IsFreeze` autoref const, and errno or fault-injection tables that
mirror C.
- A mark-and-sweep over the relocations of the `-O0 -ffunction-sections`
debug objects for C++. Almost every hit is in a function that one of the
open pull requests already deletes.
- A per-binding comparison of every native object and `*.classes.ts`
member that built-in JS consumes against `src/js`, `packages/bun-types`
and `test/`.

Self-reviewed: three changes requested, all made. The other four
`Http2Response` stubs and `socketData` go too, three more
`allocationSize` copies go too, and the `sys/Error.rs` entry is back.

Found, not deleted here:

- `"sys/Error.rs"` in `rustIdentifierPaths`
(`src/codegen/generate-js2native.ts`): no `$newRustFunction` call site
on main since 2b3f660, but #40854 adds one.
- `FrameworkFileSystemRouter.match` (the `bun:internal-for-testing`
router binding, 67 lines with `route_to_json_inverse`): no user on main,
but #40731 and #33232 add tests that call it.
- `bun_core::strings::split_once`: no user, but #40824 deletes the
adjacent `rsplit_once`.
- The SQL `queries` getter is never read, so `queries_set_cached` never
runs and `get_queries_array()` always returns `undefined`. The `if
(queries)` branches in `onResolve*`/`onReject*` (`mysql.ts`,
`postgres.ts`) and the `queries` argument of about 12 native call sites
are dead. That is a refactor of the resolve path, not a deletion.
- `NodeHTTPResponse.ref`: no JS caller, but `unref` has one, and a
one-sided pair reads like a bug.
- `MySQLConnection.ref`/`unref`: no caller, but `sql.classes.ts`
generates both drivers from one loop.
- 36 of the 48 `X_getter` functions that
`WEBCORE_GENERATED_CONSTRUCTOR_GETTER` defines in `ZigGlobalObject.cpp`
have no user. The macro also defines the live `XConstructorCallback`, so
this needs a macro split.
- `IDLByte`, `IDLShort` and `IDLLongLong` converters: never
instantiated, but `src/codegen/bindgen.ts` can emit the type names.
- `ERR_REDIS_INVALID_DATABASE` in `ErrorCode.ts`: no user, but three
open pull requests edit the adjacent lines.
- `internalBinding("quic")` constants that `quic.ts` does not read: the
object mirrors Node's list and is returned whole.

</details>

<!-- robobun:evidence:begin -->

---

**no test proof** · iteration 2 · platform-specific test(s) that do not
run on this machine, deferring to CI, which covers all platforms:
test/cli/run/run-crash-handler.test.ts

<!-- robobun:evidence:end -->
Jarred-Sumner pushed a commit that referenced this pull request Sep 24, 2026
…hs (#43840)

### Problem
- `src/codegen/generate-classes.ts` still has the DOMJIT emitter (C++
signatures, `WithoutTypeChecks` wrappers, result-type asserts, Rust
thunks). None of it can run: `define()` in `class-definitions.ts` has
set `DOMJIT = undefined` on each field since #14005 (2024-09), and all
31 `*.classes.ts` files go through `define()`.
- Nothing is left for it to bind: #35002 deleted each Rust
`*_without_type_checks` fast path, and #36756 and #36903 removed the C++
leftovers.
- A `DOMJIT:` option in a `.classes.ts` file does nothing. Five exist.

### Fix
- Delete the emitter, the option type, the strip in `define()`, the five
ignored blocks, and the stale notes next to them: 6 files, 273 lines
removed.
- The generated output is the same except for 94 empty `#if
BUN_DEBUG`/`#endif` pairs in `ZigGeneratedClasses.h` and three
DOMJIT-only `#include`s in `ZigGeneratedClasses.cpp`.
`generated_classes.rs` is byte-identical.
- Verified: the generator run before and after, `bun bd`, `tsc -p src`,
and the tests in the Notes.
- Self-reviewed: 13 concerns raised, 13 addressed (Notes).

### Background
- DOMJIT is the JavaScriptCore fast path that lets the JIT call a host
function with unboxed, type-checked arguments. The generator could emit
a C++ signature and a Rust thunk for each method.
- The hand-written DOMJIT users (`Buffer.alloc`, `performance.now`,
`bun:ffi`) do not use this generator. They stay.
- Earlier sweeps (#39249, #41169) called this removal a design call.
This PR asks for that call alone.

### Downsides
- To turn generated DOMJIT on again, a person must restore these paths
from git history and write the Rust fast paths again.
- No runtime cost found. Checked: the generated `.cpp`, `.h` and `.rs`
differ only as Fix says.

<details><summary>Notes</summary>

**Removed**
- `generate-classes.ts`: `DOMJITName`, `argTypeName`, `DOMJITType`,
`DOMJITFunctionDeclaration`, `DOMJITFunctionDefinition`,
`domJITTypeCheckFields`, `RustDOMJITArgType`. Also the `DOMJIT` branches
in `zigExportName`, `propRow`, `renderDecls`, the `expectedResultType`
asserts in the host-function wrapper, both Rust thunk loops, and the
`DOMJITAbstractHeap.h`, `FrameTracers.h`, `DFGAbstractHeap.h` includes
of the generated prologue. The destructures that named `DOMJIT` also
lose the unused `cache` and `value` bindings.
- `class-definitions.ts`: the `DOMJIT?:` option type and the two
`.map()` calls in `define()` that erased it.
- Ignored live blocks: `Crypto.randomUUID`, `Crypto.timingSafeEqual`
(`crypto.classes.ts`), `ServerWebSocket.publishText`, `publishBinary`
(`server.classes.ts`), `TextDecoder.decode` (`encoding.classes.ts`).
- Stale notes: the commented-out `// DOMJIT: {` blocks with their crash
notes on `sendText`, `sendBinary` (2023) and `getRandomValues` (#13470,
2024-08), and three orphan "DOMJIT fast path" comments in
`src/runtime/webcore/Crypto.rs` whose functions #35002 deleted.

**Self-review, and what changed because of it**
- The first draft mixed this design call with 22 log scopes and seven
fields. It now ships alone, with its history in the body.
- The leftover DOMJIT notes (`Crypto.rs`, the commented-out blocks) are
folded in.
- Three deletions that open PRs carry were dropped (#40232, #41385).
- Five items that open PRs use were taken out of the held branch
(#43283, #31855, #42819, #39222, #37518). Two `builtins.d.ts` lines were
dropped too: `src/codegen/replacements.ts` defines
`$ImportKindLabelToId`, so that declaration is live.

**History**
- #13470 (2024-08) turned DOMJIT off for `getRandomValues`. #14005
(2024-09) added the strip in `define()` as the repair for the #14001
segfault. #35224 found the cause (the wrappers returned `{ result }`
with a null exception slot) and tried to repair the generated wrappers.
A stale-PR cleanup closed it with no maintainer comment. #35002 deleted
the Rust fast paths, so the option cannot come back without new native
code.

**Kept on purpose**
- The hand-written `DomCall` path for `bun:ffi` (`src/jsc/host_fn.rs`,
`src/runtime/ffi`), the C++ DOMJIT signatures in `JSBuffer.cpp`,
`JSPerformance.cpp`, `NodeVM.cpp`, `JSSQLStatement.cpp`, and
`test/js/bun/jsc/domjit.test.ts`.

**Tests (debug build)**
- `test/js/web/encoding/text-decoder.test.js` 127 pass,
`test/js/web/web-globals.test.js` 23 pass,
`test/js/bun/util/randomUUIDv5.test.ts` 40 pass,
`test/js/bun/websocket/websocket-server.test.ts -t sendBinary` 5 pass.
- `websocket-server.test.ts -t "publish|send"`: 44 pass, 4 time out near
19 s under debug+ASAN. A debug binary built from main fails the same 4.
- `test/js/bun/jsc/domjit.test.ts`: 40 pass, 10 time out at the
100k-iteration sizes. A debug binary built from main gives the same
40/10.

**The rest of this sweep**
- Relink of the debug build with `-Wl,--gc-sections`, then the DWARF
line table of the result: 2,290 of 31,118 Rust `fn`s have no live line.
After `cargo check` on six targets only three `pub fn`s had no caller
anywhere. The 96 trait impls with no caller are the ones #43664 kept on
purpose.
- clang `-fsyntax-only -Wunused-function -Wunused-template
-Wunused-member-function -Wunused-macros` over bun's 177 C/C++
translation units (the build passes `-Wno-unused-function`): ten hits.
Open PRs delete them, or an `#if` uses them.
- oxlint `no-unused-vars` over `src/js`, `src/codegen`, `scripts`,
`packages`. cargo's `unused_dependencies` lint over four targets. A scan
for commented-out blocks (62 lines in the repo). Nothing new that is
certain.
- Each deletion was compared with the diffs of the 36 open dead-code
PRs. Left out because an open PR has it: `Bun__napi_get_version`
(#40232), two unused generator locals (#41385).

**Verified and held for the next run** (branch
`robobun/9a0817f5/dead-code-scopes-fields`, 25 files, 81 lines removed)
- 20 `declare_scope!` scopes that nothing logs to: `JSC`, `STR`,
`Bundle` and `scan_counter` (outer pair), `Store`, `hot_reloader`,
`CLI`, `LibUVBackend`, `ResolveInfoRequest`, `GetHostByAddrInfoRequest`,
`CAresNameInfo`, `GetNameInfoRequest`, `CAresReverse`, `CAresLookup`,
`quic_session`, `PathWatcherManager`, `S3Client`, `S3Stat`, `AWS`, `uws`
(`uws_sys/socket.rs`). rustc does not lint an item that another crate's
macro expands.
- Fields: `Runtime::Features.jsx_optimization_inline` with the local
`can_be_inlined`, `DebugOptions.output_file`, `ArchiveIterator.filter`,
`PackageManager.total_scripts`, `CommandLineArguments.lockfile`,
`ArgumentsSlice::_vm`. Also `struct_Channeldata` and two empty modules
in `napi_body.rs`.
- It passed `rust:check-all` (12 targets), release and `--cfg bun_debug
--cfg bun_asan` checks on linux, windows and darwin, and `cargo check
--tests` before the trim below. The trimmed commit passes `cargo check`
on linux.
- Taken out because an open PR uses the item:
`BundleOptions.code_coverage` (#43283 reads it), scope `ModuleLoader`
(#31855), scope `PROCESS` (#42819, #39222), `impl Clone for JsPoster`
and its vtable slot (#37518 rewrites the vtable).

**Follow-up candidates, not verified dead**
- `Parser Options.preserve_unused_imports_ts` is never `true`. tsconfig
`importsNotUsedAsValues` is parsed into
`preserve_imports_not_used_as_values` but never reaches the parser, in
the released binary too. This looks like a missing feature.
- `completions/bun-cli.json` (4,513 lines) and
`misctools/generate-cli-completions.ts` (728 lines): nothing in the repo
reads the JSON, but feature PRs still edit it by hand.
- `bench/snippets/runner-entrypoint.js` (244 lines): no reference, first
line says "this isn't done yet", last real change 2023-05.
- Ten `impl_timer_owner!` accessors have no caller because `dispatch.rs`
recovers the owner with its own `owner!` macro. Which mechanism stays is
a design call.
- `mordant-baseline.toml` still counts about 170 `unused_pub` findings
(`sys/lib.rs` 56, `libuv_sys/libuv.rs` 41, `errno/windows_errno.rs` 31).
`bun run rust:mordant` names them.

</details>
Jarred-Sumner pushed a commit that referenced this pull request Sep 24, 2026
…43880)

Behaviour change: none

### Problem
- Three declarations have no reference anywhere in the tree, on any
platform.
- A link of the debug build with `--gc-sections` drops the two C++
functions. A `#[deprecated]` probe on the Rust struct gives zero use
warnings on all 12 CI targets.

### Fix
- Remove `createBuffer(JSGlobalObject*, const Vector<uint8_t>&)`
(`JSBuffer.cpp`, `JSBuffer.h`). All 9 call sites pass a `std::span` or a
pointer and a length.
- Remove `expectedEnumerationValues<BufferEncodingType>()`
(`JSBufferEncodingType.cpp`, `JSBufferEncodingType.h`). Nothing converts
`IDLEnumeration<BufferEncodingType>`, so nothing instantiates it.
- Remove the `#[cfg(windows)]` stub `struct WaitPidResult {}`
(`src/spawn/process.rs`). Each user of the name, and the re-export in
`src/spawn/lib.rs`, is `#[cfg(unix)]`.
- Verified: `bun run rust:check-all` (12 targets ok), `cargo fmt --all
--check`, `bun bd`, and with the debug build
`test/js/node/buffer.test.js` (683 pass), `test/js/node/vm/vm.test.ts`
(306 pass), `test/js/web/websocket/websocket-client.test.ts` (37 pass).

### Background
- This sweep used two whole-program checks, not name searches. The
linker reports each function section that no root reaches. The compiler
reports each use of an item marked `#[deprecated]`, with exact name
resolution, for each target.
- The probe covered 11,196 Rust items (functions, extern declarations,
constants, statics, structs, enums, aliases). It ran on 12 targets, and
also with tests, with `--release`, and with the `bun_asan`, `bun_debug`
and `socket_fault_injection` cfgs. 145 items have zero uses. Open PRs
already delete 134 of them, so this PR leaves those out.

### Downsides
- None found. Checked each textual reference of the three names in
`src/`, `packages/`, `scripts/`, `build/debug/codegen/` and the export
lists (`src/symbols.txt`, `src/symbols.def`, `src/linker.lds`).

<details><summary>Notes</summary>

Areas scanned in this run

- Rust: the whole workspace. Functions with no live symbol in a
`--gc-sections` link of the debug build (whole-archive over every
`bun_*` rlib), every `extern` block declaration, constants, statics,
structs, enums, unions and type aliases with few outside references.
Items under a platform `cfg` were evaluated against the cfg set of each
CI target and probed on the targets where they are active. The
crate-level `allow(deprecated)` in `bun_jsc` and `bun_ptr` was off
during the probe.
- C and C++: every function in `src/`, `packages/bun-usockets` and
`packages/bun-uws` that the `--gc-sections` link drops (298 source
locations). Open PRs already delete 183 of them.
- `src/js/`: no file is unloaded, no internal export is unused, no
builtin is unreferenced (outside files that open PRs cover).
- Headers that nothing includes, `.rs` files outside every module tree,
`.cpp` files outside the build, `#if 0` blocks, unreferenced top-level
TS/JS definitions, unused `[workspace.dependencies]` entries: none found
outside files that open PRs cover.

Candidates that the checks flagged and this PR keeps

- `Bun__napi_get_version` (`napi.cpp`): no caller, but #40232 already
removes it under its earlier name `napi_internal_get_version`.
- `host_fn::host_fn_this_value`, `host_fn::host_fn_setter`
(`src/jsc/host_fn.rs`): no use today, but
`src/codegen/generate-classes.ts` emits both names for a class that is
not shared.
- `JsClass::estimated_size` default (`src/jsc/lib.rs`): a documented
hook that generated code resolves by method syntax.
- `bun_zstd::inflate_embedded`, `inflate_embedded_nul`: used by
`embed_compressed!` under `cfg(bun_codegen_embed)`, which only release
builds set.
- `bun_core::strings::split_once`: no caller, but `clippy.toml` names it
as the replacement in three `disallowed-methods` reasons.
- `src/runtime/api/bun/h2/connection.rs` (`send_header_block`,
`send_data`, `send_push_promise`, `encode_header`,
`begin_header_block`): only unit tests call them, and the engine is
still under construction.
- `_ASSERT`, `_FITS`, `_ALIGN_CHECK`, `_NOT_SEND`, `_NOT_SYNC`: static
assertions.
- `PerformanceResourceTiming::create`, `ResourceTiming`,
`NetworkLoadMetrics` and related classes: nothing creates an instance,
but `PerformanceResourceTiming`, `PerformanceServerTiming` and
`PerformanceTiming` are globals, so the classes are API surface.
- Unused integer specializations in `JSDOMConvertNumbers.cpp`, unused
`toJS`/`toWrapped` overloads in generated-style WebCore wrappers, unused
special members in `ncrypto.cpp`, constants in the `sys`, `libuv_sys`
and `errno` tables: each is part of a complete table or a class shape.

</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 -->
Jarred-Sumner pushed a commit that referenced this pull request Sep 24, 2026
…ndings, NodeVMModule, and the build scripts (#43914)

Behaviour change: none

### Problem
- 38 lines in 23 files have no reader: 14 type aliases, one enum, three
locals, three build-script leftovers, nine stale config entries.
- The sweep found no other free dead code. The 37 open dead-code PRs
already delete each larger item. This PR shares no deletion with them.

### Fix
- Remove `using DOMWrapped` from 14 wrapper headers (`JSAbortSignal.h`,
`JSBroadcastChannel.h`, `JSCloseEvent.h`, `JSCustomEvent.h`,
`JSErrorEvent.h`, `JSMessageEvent.h`, `JSMessagePort.h`,
`JSPerformance.h`, `JSPerformanceMark.h`, `JSPerformanceMeasure.h`,
`JSPerformanceResourceTiming.h`, `JSWebSocket.h`, `JSWorker.h`,
`JSWebView.h`).
- Remove `NodeVMModule::Type` and three locals that nothing reads:
`contents` (`CryptoPrimes.cpp`), `dataString` and `encodingString`
(`JSCipherPrototype.cpp`).
- Remove `ToolSpec.versionArg` (`scripts/build/tools.ts`), the
`sys/Error.rs` key of `rustIdentifierPaths` (`generate-js2native.ts`),
and the `internalRegistry` field that `createInternalModuleRegistry`
returns. Remove eight entries of `.gitattributes`, `.prettierignore` and
`oxlint.json` that name paths that do not exist, and one duplicate
pattern.
- Verified: `rg` finds no other use of each name in `src/`, `packages/`,
`scripts/`, `test/` and `build/debug/codegen/`. `bun bd` passes. With
the debug build: `abort.test.ts`, `broadcast-channel.test.ts`,
`websocket-client.test.ts`, `perf_hooks.test.ts`, `vm.test.ts`,
`test-crypto-prime.js`, `test/internal/source-lints/`.

### Background
- `DOMWrapped` names the C++ class that a JS wrapper class wraps.
`JSDOMWrapper<T>` defines it for each wrapper. Only `JSDOMIterator.h`
reads it, for `JSFetchHeaders`, `JSDOMFormData`, `JSURLSearchParams` and
`JSCookieMap`. None of those four declares its own alias.
- `ToolSpec` describes a tool that the build looks for on the PATH.
`versionArg` was for a tool that prints its version with `version` and
not `--version`. No tool spec sets it.

### Downsides
- None found. Checked each name with `rg`, the debug build, and the
suites above.

<details><summary>Notes</summary>

How this sweep searched

- Rust: a rust-analyzer reference index of the whole workspace (49,127
items), then a mark and sweep from these roots: FFI and test attributes,
trait items, macro-generated items, names that the generated code uses,
and names with a textual occurrence that the index did not resolve.
After the false positives were removed (macro dispatch such as
`any_dispatch!`, `comptime_string_map!` statics, struct field shorthand,
the codegen name `r#ref`), no unreferenced item was left outside the
open PRs.
- C, C++ and Rust: a relink of the debug build with `--gc-sections
--print-gc-sections`. The debug build has no inlining, so a dropped
function section has no caller on linux-x64. The relink dropped 337
C-named functions and 166 plain C++ functions from Bun's own objects.
The open PRs already delete them, except the items under "Kept" below.
- `src/js/`: every builtin export has a `CodeGenerator` reference, every
internal module has a loader, and no module-local binding is unused.
- `.rs` files outside every module tree, headers that nothing includes,
`.cpp` files outside the build, unused Cargo dependencies (`cargo`
reports 9 on linux. Open PRs already remove 4. The other 5 have a use on
another target or in tests): nothing to remove.

Kept, with the reason

- `WEBCORE_GENERATED_CONSTRUCTOR_GETTER` (`ZigGlobalObject.cpp`) defines
a `<Name>_getter` for 51 classes. Only 15 have a user. To remove the
other 36 needs a second macro, which adds lines.
- `PerformanceResourceTiming`, `ResourceTiming`, `NetworkLoadMetrics`,
`ResourceLoadTiming`: nothing creates an instance, but
`PerformanceResourceTiming` is a global constructor, so the class is API
surface.
- `bun_core::strings::split_once`: no caller, but `clippy.toml` names it
as the replacement for `str::split_once`.
- `StringPrintStream pathOut` (`BunJSCModule.h`): an unread local, but
#41137 already removes that line in its rewrite of
`startSamplingProfiler`.
- `jsFunctionAppendOnLoadPluginNode` and three sibling host functions,
`Process_defaultSetter`, `Bun__napi_get_version`: no caller, already
removed by #40232.
- `completions/bun-cli.json` and
`misctools/generate-cli-completions.ts`: nothing reads the JSON, but
feature PRs keep it up to date by hand.
- `scripts/lldb-inline-tool.cpp`, `scripts/lldb-inline.sh`,
`scripts/github-metrics.ts`, `scripts/gamble.ts`: nothing references
them, but they are manual developer tools.
- `HiveBitSet::_FITS` (`src/collections/hive_array.rs`): a static
assertion, so it stays. It has a defect outside the scope of this PR: it
is an associated const of a generic impl and nothing references it, so
rustc never evaluates it. A reference such as `let () = Self::_FITS;` in
`init_empty()` makes it run.
- The defaulted special members in `ncrypto.cpp`, and the `CMAKE_*`
exports in `flake.nix` and `shell.nix` (not testable here).

</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 -->
Jarred-Sumner pushed a commit that referenced this pull request Sep 25, 2026
… the build scripts (#43778)

### Problem
- A few C++ and TypeScript items have no caller, no producer, or no
effect.
- `BUN_MESSAGEPORT_USES_PIPE` (`src/jsc/bindings/webcore/MessagePort.h`)
is always `1`. The `#if` around all of `MessagePortPipe.cpp` never
excludes anything.

### Fix
- WebView: remove `WebViewProto::Reader::u16()` and `f32()`
(`ipc_protocol.h`), which have no caller. Remove the CDP `Method` values
`RuntimeEnable`, `TargetCloseTarget` and `InputDispatchScrollEvent` with
their `case` labels (`ChromeBackend.{h,cpp}`). No pending entry carries
them.
- WebCore bindings: remove the `BUN_MESSAGEPORT_USES_PIPE` define and
guard, the self-alias of `ExtendedDOMClientIsoSubspaces`, the forward
declaration of `URLPatternUtilities::URLPatternInit` (no such type), the
enumerators `PerformanceEntry::Type::Paint` and
`CastedThisErrorBehavior::ReturnEarly`, and 13 lines of commented-out
WebKit code.
- Build scripts: remove `getBuildNumber()` (`.buildkite/ci.ts`) and
`BunOutput.rustObjects` (`scripts/build/bun.ts`). Nothing reads either.
- Verified: `rg -w` for each symbol over `src`, `packages`, `scripts`,
`test` and `build/debug/codegen` finds no other use. `bun bd` passes.
The Notes list the tests.

### Background
- `ipc_protocol.h` is the wire format between bun and the WebView host
process. `Reader` decodes frames. Every caller uses `u8`, `u32`, `bytes`
and `str` only.
- `ChromeBackend` tags each pending Chrome DevTools Protocol command
with a `Method`, so that the response handler knows which promise to
settle. A value that no pending entry carries cannot reach the `switch`.
- #29937 added the guard so that `MessagePortPipe.cpp` compiled to
nothing while a verification step reverted `MessagePort.h`. Both files
are on main now.

### Downsides
- None found. Checked each removed symbol for users in C++, Rust,
generated code and `src/symbols.*`. The removed enum values are
in-memory tags or template arguments. Rust mirrors neither enum.

<details><summary>Notes</summary>

Smoke tests with the debug build, all pass:
`test/js/web/workers/message-port-pipe.test.ts`,
`message-channel.test.ts`, `performance-observer-leak.test.ts`,
`test/js/node/perf_hooks/perf_hooks.test.ts`, `test/js/web/urlpattern/`,
`test/js/bun/webview/webview-chrome-pipe.test.ts`. `clang-format` and
`prettier` report no change on the touched files. `.buildkite/ci.ts`
still transpiles.

Each removal was checked against the diffs of the 34 open dead-code PRs.
None of them removes the same lines. `MessagePort.h` is also touched by
#40525, in a different hunk.

How the Rust side was scanned, and why this PR has no Rust in it:
- `cargo mordant` at the revision pinned in
`.github/workflows/rust-lints.yml`, over the Linux, Windows and macOS
targets, with the `unused_pub` entries taken out of the baseline. It
reports 188 `pub` items that nothing in the workspace uses. Every
function, method and struct in that list is in one of four groups: an
open PR already removes it, a `cfg` that the run does not build uses it
(`bun_zstd::inflate_embedded*` under `bun_codegen_embed`,
`StoredTrace::from` in `PackageInstall.rs`), only a unit test uses it
(`CowSliceZ::init_dupe`), or #42119 left it on purpose
(`host_fn_this_value`, `host_fn_setter`, `JsClass::estimated_size`). The
constants are flag, errno and syscall-tag tables.
- A rust-analyzer SCIP index for five targets (Linux, Windows, macOS,
FreeBSD, Android) plus a reachability closure over it. Two blind spots
make it unreliable alone: rust-analyzer sets `cfg(test)` by default,
which hides `src/runtime/bin_entry`, and references that come from a
`macro_rules!` body are not indexed (`comptime_string_map!`, the CSS
`to_css` bridges). With those corrected, it agrees with mordant and adds
nothing.
- Cargo's own `unused_dependencies` warnings: 9 edges. Each is used on
another target, or #40294 already removes it.
- Rust files outside every module tree: none. Headers that nothing
includes: none (the remaining ones come in through
`GeneratedJS2Native.h`, `NativeModuleImpl.h` or `include_bytes!`).

Also scanned and clean: `src/js/{node,internal,bun,thirdparty}` and
`src/js/builtins` (all 50 builtins and all 177 private names have a
user), `scripts/`, `misctools/`, `.buildkite/ci.ts`, and the C++ under
`webcore/`, `webcrypto/`, `node/` and `src/runtime/` that no open PR
touches.

Probably dead, left alone on purpose:
- `bun_core::strings::split_once` (`src/bun_core/string/immutable.rs`):
no caller on any target. It sits next to the hunk in which #40824
removes `rsplit_once`, so a removal here would conflict with that PR.
- The raw-list `myersDiff` export of
`src/js/internal/assert/myers_diff.ts` and the `Output::List` path
behind it in `src/runtime/node/node_assert.rs` (about 115 lines):
nothing consumes it. #39924 kept the export on purpose, and Node's own
`test-assert-myers-diff.js` needs it if that test is vendored.
- `BuiltinName::{redirect, asyncIterator, name, default, fatal,
ignoreBOM}` (`src/jsc/lib.rs`, mirrored by position in `bindings.cpp`):
never constructed. A removal conflicts with #40232.
- `FetchHeaders` guard handling (`removePrivilegedNoCORSRequestHeaders`
and the `Guard::Immutable` checks): every construction site passes
`Guard::None`, and #43644 removes `setGuard`. This is unreachable code,
not unreferenced code.
- `ServerTiming`'s constructor and its `durationSet` / `descriptionSet`
fields: nothing constructs a `ServerTiming`. #40122 and #41385 touch the
same cluster.
- The `$isPromiseFulfilled`, `$isPromiseRejected` and `$alwaysInline`
codegen macros: no user since 92459cd.
- `scripts/build/config.ts` flags `logs` and `baseline`: parsed and
printed, never read since the Rust rewrite.
`NestedCmakeBuild.{extraCFlags, extraCxxFlags, libSubdir, sourceSubdir,
pic}`: no dependency sets them, but `scripts/build/deps/README.md`
documents them as the API for future dependencies.
- `misctools/gen-unicode-table.ts` and `unicode-generator.ts` emit Zig.
Nothing references them, but `src/bun_core/string/identifier.rs` still
names the generator as the way to rebuild its tables.
- `completions/bun-cli.json` and
`misctools/generate-cli-completions.ts`: nothing in the repository reads
the JSON. It is still updated by hand, so something outside the
repository may use it.

</details>
Jarred-Sumner pushed a commit that referenced this pull request Sep 25, 2026
### 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 -->
Jarred-Sumner pushed a commit that referenced this pull request Sep 26, 2026
… 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>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants