Remove dead code from webcore bindings, watcher, node-fallbacks, and misc crates
Closed
RO
3mo ago+58+58+01234567890123456789-2448-2448-0123456789012345678901234567890123456789
Scheduled dead-code sweep. Net -1,936 lines across 82 files (+177/-2,113). Areas were chosen to avoid overlap with the open dead-code PRs (#35437, #35775, #35880, #36115, #36237, #37012); all hunks were diffed against those PRs and none of the deletions coincide.
What was removed
webcore C++ bindings (~900 lines)
JSDOMConvertBufferSource.h: 11 unused typed-array IDL types (IDLInt8Array,IDLFloat64Array,IDLBigUint64Array, ...) with theirConverter/JSConverterspecializations and 25toPossiblyShared*/toUnshared*helpers. OnlyIDLUint8Array,IDLArrayBuffer,IDLDataView, andIDLArrayBufferViewhave consumers.IDLTypes.h:IDLDate,IDLUnsupportedType,IDLError,IDLDOMException,IDLScheduledAction,IDLIDBKey/IDLIDBKeyData/IDLIDBValue, theENABLE(WEBGL)block, and dead forward declarations.JSDOMPromiseDeferred.h/.cpp: theDOMPromiseDeferredBase/DOMPromiseDeferred<T>class cluster,resolveWithJSValue,resolveWithNewlyCreated,resolveCallbackValueWithNewlyCreated,fulfillPromiseWithJSON+parseAsJSON.NetworkLoadMetrics.h:AdditionalNetworkLoadMetricsForWebInspector,PrivacyStance,NetworkLoadPriority, the write-only connection flags, and thePLATFORM(COCOA)copyTimingDatadecls.Event.h/.cpp: write-onlym_defaultHandled/m_isDefaultEventHandlerIgnoredbits and their accessors, the now-emptyresetBeforeDispatch, and never-overriddenrelatedTargetvirtuals.- Smaller:
IDLOperationReturningPromise::callReturningOwnPromise/callStaticReturningOwnPromise,IDLAttribute::setPassingPropertyName/setStatic,HTTPHeaderIdentifiers::identifierFor+ its pointer-to-member table,EventTarget::isNode,ContextDestructionObserver::protectedScriptExecutionContext,PerformanceTiming::monotonicTimeToIntegerMilliseconds,BufferSource::mutableData,toBufferSource,FetchHeaders::fastSet,ScriptWrappable::offsetOfWrapper, and friends. JSDOMConvertDate.h/.cpp,JSMIMEBindings.h/.cpp, andJSDOMIterator.cppare stubbed out following the existing convention for superseded files (see the stub comment inMessagePortChannel.h).
build/codegen
src/codegen/generate-unified-source-bundles.rb(392 lines): CMake-era ruby script;scripts/build/unified.tsis the live reimplementation and nothing invokes ruby.
node-fallbacks
util.js: 270-line commented-out legacyutil.typesbody (stale since 2025).package.json/bun.lock: 13 dependencies no fallback imports (the force-externalized builtin names never resolve to node_modules), includingesbuild.tsconfig.jsonpaths trimmed to match.
file watcher
WatchItem.loaderwas write-only: everyadd_filepath stored it, no MultiArrayList column accessor ever read it. Removed the column, thebun_watcher::Loadercycle-break newtype, its drift-guard assert, and the loader parameter from the wholeadd_file/add_file_by_path_slowchain (watcher, hot_reloader, bundler, jsc_hooks, RuntimeTranspilerStore, AsyncModule, VirtualMachine, test_command).AsyncModule.loaderandInitOpts.loaderfell out as dead once the watcher stopped storing it.
Rust crates
sha_hmac: unused OpenSSL-3-deprecated hashers (hashers::SHA512/SHA384/SHA512_256/RIPEMD160) and the never-wiredMD5_SHA1/Blake2EVP wrappers.csrf:Error::InvalidToken/ExpiredToken/DecodingFailed, never constructed (verify()returns bool).valkey: sixRedisErrorvariants the parser never produces (InvalidArgument,InvalidArray,InvalidBigNumber,InvalidErrorString,InvalidNull,InvalidSimpleString); the one string-parse site feeds from the runtime error name set, which contains none of them.picohttp: write-onlyRequest.minor_version/bytes_readfields (Responsekeeps both).windows_sys: consts, types, and extern decls whose only references were unused re-exports (SetFileInformationByHandle,ResumeThread,FILE_ATTRIBUTE_*,CTRL_LOGOFF_EVENT,PebView,Curdir,STATUS_SUCCESS, ...), plus those re-export lines.zlib/zlib_sys:deflateInit_/inflateInit_decls (all code uses the*2_variants).libarchive,css_jsc: commented-out Zig code left from the port.opaque: theopaque_mut_nnmacro arm (zero call sites across ~180 instantiations).bake:BakeProdSourceMapno_mangle export C++ never declares or calls.BunObject: the Rustnanosecondshost_fn shadowed by the C++functionBunNanosecondsthe lut actually uses, plus stalemacro(...)entries inBunObject+exports.h.- Misc:
exe_formatInputIsSigned,mdSetextheader,myers_diffOutOfMemory,node_fsunused trait method, unused re-export tokens innode.rs/sql_jsc/resolver.
built-in JS
internal/repl/node-primordials.js: 14 export keys none of the 13 repl/readline consumers reference, with their backing captures.internal-for-testing.ts:npa,npmTag,lsanDoLeakCheck(plus its C++ backing), all with zero references in test/, bench/, or scripts/.- Unused export keys in
internal/fs/watch.tsandinternal/readline/interface.js.
Verification
- Every symbol rg'd across src/, packages/, test/, and build/debug/codegen before deletion, including token-pasted C++ names,
$zig/$cppstring references, and strum string-construction paths. cargo check --workspaceon all 10 CI target triples (bun run rust:check-all): 10 ok, 0 failed.- Full
bun bddebug build passes. - The dead-code escape inventory (
dead-code-escape-limits.json) was regenerated. A source-lint file pinning the removals was part of earlier revisions and removed during review. - Smoke tests pass: fetch headers, performance entries, abort GC, CryptoHasher, CSRF, watch mode, browser bundling (node-fallbacks), readline. 582 tests, 0 failures.
[review] gate passed · iteration 1 · 89 files touched
fails on main (without fix)
ASAN without fix: 4 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts
bun test v1.4.0 (c16c60eb6)
test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts:
19 | return readFileSync(path.join(repoRoot, p), "utf8");
20 | }
21 |
22 | function expectAbsent(checks: Array<[string, RegExp]>) {
23 | for (const [file, re] of checks) {
24 | expect(re.test(src(file)), `${file} should not match ${re}`).toBe(false);
^
error: src/jsc/bindings/webcore/JSDOMConvertBufferSource.h should not match /\bIDLBigUint64Array\b/
Expected: false
Received: true
at expectAbsent (/workspace/bun/test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts:24:66)
at <anonymous> (/workspace/bun/test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts:29:3)
(fail) dead webcore C++ symbols do not reappear [24.52ms]
19 | return readFileSync(path.join(repoRoot, p), "utf8");
20 | }
21 |
22 | function expectAbsent(checks: Array<
... (truncated)
release without fix: 4 FAILED
bun test v1.4.0-canary.1 (5c4db5bde)
test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts:
19 | return readFileSync(path.join(repoRoot, p), "utf8");
20 | }
21 |
22 | function expectAbsent(checks: Array<[string, RegExp]>) {
23 | for (const [file, re] of checks) {
24 | expect(re.test(src(file)), `${file} should not match ${re}`).toBe(false);
^
error: src/jsc/bindings/webcore/JSDOMConvertBufferSource.h should not match /\bIDLBigUint64Array\b/
Expected: false
Received: true
at expectAbsent (/workspace/bun/test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts:24:66)
at <anonymous> (/workspace/bun/test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts:29:3)
(fail) dead webcore C++ symbols do not reappear [0.39ms]
19 | return readFileSync(path.join(repoRoot, p), "utf8");
20 | }
21 |
22 | function expectAbsent(checks: Array<[string, RegExp]>) {
23 | for (const [file, re] of checks) {
24 | expect(re.test(src(file)), `${file} should not match ${re}`).toBe(false);
... (truncated)
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/dead-symbols-webcore-watcher-fallbacks.test.ts
bun test v1.4.0 (c16c60eb6)
test/internal/source-lints/dead-symbols-webcore-watcher-fallbacks.test.ts:
(pass) dead webcore C++ symbols do not reappear [43.13ms]
(pass) watcher loader column stays deleted [5.67ms]
(pass) dead Rust symbols do not reappear [46.06ms]
(pass) dead JS builtin exports do not reappear [9.41ms]
4 pass
0 fail
60 expect() calls
Ran 4 tests across 1 file. [2.09s]
__F:0:S:0
release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 673ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/130] install /workspace/bun/src/node-fallbacks
bun install v1.4.0-canary.1 (5c4db5bde)
Checked 111 installs across 104 packages (no changes) [3.00ms]
[2/130] gen node-fallbacks/react-refresh.js
Bundled 1 module in 3ms
react-refresh.js 4.81 KB (entry point)
[3/130] gen ErrorCode+*.h
[4/130] gen generated_host_exports.rs
generated_host_exports.rs: 92 exports (host=3, lazy=10, generic=79, rust=0); 239 extern-C blocks audited
[5/130] gen node-fallbacks/*.js
[6/130] gen cpp.rs (cppbind)
[7/130] gen JS modules (bundle-modules)
Preprocess modules (8633ms)
Bundle modules (47ms)
Postprocesss modules (258ms)
Bundle Functions (650ms)
Generate Code (23ms)
[9.63s] Bundled "src/js" for production
2569 kb
193 internal modules
13 native modules
84 internal functions across 17 files
[7/129] cargo bun_bin → libbun_rust.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_opaque v0.0.0 (
... (truncated)
diff hotspot
src/bun_core/windows_sys.rs | 2 +-
src/bundler/bundle_v2.rs | 5 +-
src/codegen/generate-js2native.ts | 1 -
src/codegen/generate-unified-source-bundles.rb | 392 ---------------------
src/csrf/lib.rs | 3 -
src/css_jsc/css_internals.rs | 11 -
src/exe_format/pe.rs | 2 -
src/http/lib.rs | 4 -
src/install_jsc/dependency_jsc.rs | 211 -----------
src/install_jsc/lib.rs | 8 +-
src/install_jsc/update_request_jsc.rs | 91 -----
src/js/internal-for-testing.ts | 11 -
src/js/internal/fs/watch.ts | 2 +-
src/js/internal/readline/interface.js | 1 -
src/js/internal/repl/node-primordials.js | 23 +-
src/jsc/AsyncModule.rs | 6 -
src/jsc/RuntimeTranspilerStore.rs | 2 -
src/jsc/VirtualMachine.rs | 4 +-
src/jsc/bindings/BunObject+exports.h | 6 -
src/jsc/bindings/ErrorCode.ts | 4 -
src/jsc/bindings/IDLTypes.h | 50 +--
src/jsc/bindings/InternalForTesting.cpp | 15 +-
src/jsc/bindings/InternalForTesting.h | 1 -
src/jsc/bindings/ZigGlobalObject.cpp | 1 -
src/jsc/bindings/webcore/BufferSource.h | 13 -
.../webcore/ContextDestructionObserver.cpp | 5 -
.../bindings/webcore/ContextDestructionObserver.h | 1 -
src/jsc/bindings/webcore/Event.cpp | 7 -
src/jsc/bindings/webcore/Event.h | 12 -
src/jsc/bindings/webcore/EventTarget.cpp | 6 -
src/jsc/bindings/webcore/EventTarget.h | 2 -
src/jsc/bindings/webcore/FetchHeaders.h | 1 -
src/jsc/bindings/webc
... (truncated)
gate history · 2 passed · 1 rejected · iteration 1
evidence per changed file
file reads edits tests
src/bun_core/windows_sys.rs 0 0 0
src/bundler/bundle_v2.rs 0 0 0
src/codegen/generate-js2native.ts 0 0 0
src/codegen/generate-unified-source-bundles.rb 0 0 0
src/csrf/lib.rs 0 0 0
src/css_jsc/css_internals.rs 0 0 0
src/exe_format/pe.rs 0 0 0
src/http/lib.rs 0 0 0
src/install_jsc/dependency_jsc.rs 0 0 0
src/install_jsc/lib.rs 0 0 0
src/install_jsc/update_request_jsc.rs 0 0 0
src/js/internal-for-testing.ts 0 0 0
src/js/internal/fs/watch.ts 0 0 0
src/js/internal/readline/interface.js 0 0 0
src/js/internal/repl/node-primordials.js 1 0 0
src/jsc/AsyncModule.rs 0 0 0
(+ 73 more files)