Remove dead code from FFI sys crates, bun_core, built-in JS, codegen, and build scripts

Merged
RO
3mo ago
+367-2419

Removes 2,255 lines (net -2,057) of verified-dead code across 116 files: unused pub items the dead_code lint cannot see (it treats every pub item as an external API root), unreferenced FFI declarations, orphaned files, stale commented-out C++ blocks, and dead build-script helpers.

Method: started from scripts/find-dead-exports.ts, narrowed 8,259 candidates to 1,039 whose name appears in exactly one file across src/, scripts/, test/, and regenerated build/debug/codegen/ output, then demoted each to private and let the workspace's dead_code = deny prove which were genuinely unreferenced. Items the compiler proved live (macro expansions, return-position escapes, cfg(windows)/cfg(darwin) usage, codegen references) were restored; the rest were deleted. Areas with open dead-code PRs (#36237, #35775, #36115, #35437, #35880) were excluded, and the one overlapping deletion found during final diffing (kGetNativeReadableProto, already in #35775) was dropped from this PR.

Removed

FFI declaration crates (unused imports of vendored C functions; declarations only, no link-time effect):

  • src/mimalloc_sys/mimalloc.rs: ~100 declarations (heap-local variants mi_heap_*, stats/options surface mi_stats_* mi_option_*, posix shims mi_posix_memalign/mi_valloc/mi_pvalloc, C++ mi_new_* family)
  • src/windows_sys/externs.rs: never-constructed WinsockError + ~100 WSA* error consts, GetBinaryTypeW, CreateJobObjectW, M128A kept (used by CONTEXT on windows)
  • src/zlib_sys/win32.rs: 44 declarations (gz* file API, deflateTune, inflateUndermine, zlibCompileFlags, ...)
  • src/cares_sys/c_ares.rs: 21 (option/server-config surface ares_set_servers*, ares_mkquery, ares_parse_txt_reply_ext, ...)
  • src/lsquic_sys/lib.rs: 11 (handshake/conn status consts, stream-ctx helpers)
  • src/brotli_sys, src/boringssl_sys, src/libdeflate_sys: 17 combined (BrotliEncoder* estimators, TLS_with_buffers_method, libdeflate_*_decompress, ...)

Rust runtime/support crates:

  • src/bun_core/env.rs: BuildTarget::Wasi variant + IS_WASI (never constructed; IS_BROWSER simplifies to IS_WASM)
  • src/jsc/HTTPServerAgent.rs: 5 unused Rust-side imports of Bun__HTTPServerAgent__notify* + 2 type aliases
  • src/runtime/test_runner/mod.rs: JSGlobalObjectTestExt::throw2 (duplicated throw_error)
  • src/runtime/server/NodeHTTPResponse.rs: unused pause_socket sibling cleanup; pause_socket_reads kept (referenced by generated bindings)
  • ~230 surviving demotions of file-local pub items to private across 60 crates, which moves them permanently under dead_code analysis
  • assorted single items: dead re-export lines in sql_jsc/sourcemap_jsc/bundler_jsc/runtime/api.rs, EventLoopGuard-adjacent aliases, unused imports

Built-in JS / codegen / build scripts:

  • src/node-fallbacks/timers.promises.js (238 lines): never registered in src/resolver/node_fallbacks.rs's 23-module registry, so it was built and compressed on every build but could never be served
  • src/js/internal/crypto/x509.ts + its row in ProcessBindingNatives.cpp: process.binding("crypto/x509") is implemented natively in BunProcess.cpp
  • src/js/internal/validators.ts: validateUndefined, validateSignalName/validatePlainFunction export entries
  • src/js/internal/{shared,tls,streams/utils}.ts: dead export-object entries (definitions stay where used in-file); primordials.js: 5 dead scalar-constructor keys (typed-array keys kept: util.inspect reaches them via computed primordials[tag] access)
  • src/codegen: camelCase, pascalCase, warnOnIdentifiersNotPresentAtRuntime, DOMJITReturnType, ownRow, cppPointer
  • scripts/build: explainFlags (no --explain-flags exists), assertDefined, depSourceStamp; root package.json bump script (its target was deleted in #13427)

Orphaned files: src/fixtures_example.com.html, src/zlib.test.txt + src/zlib.test.gz (2021 inline-test fixtures), src/fallback.html (only fallback-backend.html is embedded), src/logo.svg, src/favicon.png

Stale commented-out C++ blocks (~243 lines, all >6 months old via git blame): minicoro scaffolding in coroutine.cpp (2022), pasted Node JS source in JSX509CertificatePrototype.cpp, commented BINDING_INTEGRITY vtable checks, InspectorInstrumentation calls in WebSocket.cpp, suspended-event-loop paths in JSDOMPromiseDeferred.cpp, commented-out function bodies in Performance.cpp/Event.cpp/DOMWrapperWorld.cpp/ErrorEvent.cpp and 8 more webcore files

Verification

cargo check --workspace            # green (dead_code/unreachable_pub/unused_* all deny)
bun run rust:check-all             # 10/10 targets (linux/macos/windows/freebsd/android x arches)
bun bd                             # full debug build with freshly regenerated codegen
bun test test/internal/source-lints/   # 65 pass (includes the new pin test below)
bun bd test test/js/node/fs/fs.test.ts            # 445 pass
bun bd test test/js/node/http/node-http.test.ts   # 144 pass, 1 env-dependent proxy failure also fails on released bun
bun bd test test/js/bun/glob/match.test.ts        # 29 pass
bun bd test test/js/bun/resolve/resolve.test.ts   # 50 pass

test/internal/source-lints/dead-symbols-pub-exports-sweep.test.ts pins representative removed symbols and the deleted files against reintroduction.

The compiler-driven loop caught and restored every false positive the textual scan missed: methods on types that escape only via return position (StdinReader::take_byte, HeaderSet::pairs, bitset iterators), macro-referenced items (comptime_string_map! statics, $crate:: paths), platform-gated items (EmptyCopyFileState on darwin/freebsd, M128A/WriteKind on windows), and generated-binding references (get_insecure_http_parser, pause_socket_reads) which only appear after codegen reruns.

Followups (not removed)

  • patches/ncrypto.patch (919 lines) is referenced by nothing in scripts/build/deps/*.ts while every other patch file is; src/jsc/bindings/ncrypto.{h,cpp} already exist in patched form. Possibly kept as upstream-sync documentation, so left alone.
  • The #if ENABLE(BINDING_INTEGRITY) extern vtable scaffolding in JSCustomEvent.cpp/JSPerformanceServerTiming.cpp lost its only (commented) consumer but matches upstream WebKit codegen shape; left in place.
  • .github/workflows/release.yml:2 references .buildkite/scripts/release.sh, which no longer exists (comment only).
  • src/react_compiler and src/ini were deliberately excluded: the former carries explicit not-yet-wired port markers, the latter's candidates proved live on inspection.

[decide:dep] gate passed · iteration 3 · 126 files touched

fails on main (without fix)
ASAN without fix: 2 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-pub-exports-sweep.test.ts
bun test v1.4.0 (a9da3237f)

test/internal/source-lints/dead-symbols-pub-exports-sweep.test.ts:
78 |     ["src/libdeflate_sys/libdeflate.rs", /\bfn libdeflate_gzip_decompress\b/],
79 |     ["src/brotli_sys/brotli_c.rs", /\bfn BrotliEncoderEstimatePeakMemoryUsage\b/],
80 |     ["src/boringssl_sys/boringssl.rs", /\bfn TLS_with_buffers_method\b/],
81 |   ];
82 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
83 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/windows_sys/externs.rs: \bfn GetBinaryTypeW\b",
+   "src/windows_sys/externs.rs: \bfn CreateJobObjectW\b",
+   "src/windows_sys/externs.rs: \bstruct WinsockError\b",
+   "src/windows_sys/externs.rs: \bWSA_QOS_ESHAPERATEOBJ\b",
+   "src/mimalloc_sys/mimalloc.rs: \bfn mi_stats_print\b",
+   "src/mimalloc_sys/mimalloc.rs: \bfn mi_reserve_huge_os_pages_interleave\b",
+   "src/
... (truncated)

release without fix: 2 FAILED
bun test v1.4.0-canary.1 (57ae5f0a5)

test/internal/source-lints/dead-symbols-pub-exports-sweep.test.ts:
78 |     ["src/libdeflate_sys/libdeflate.rs", /\bfn libdeflate_gzip_decompress\b/],
79 |     ["src/brotli_sys/brotli_c.rs", /\bfn BrotliEncoderEstimatePeakMemoryUsage\b/],
80 |     ["src/boringssl_sys/boringssl.rs", /\bfn TLS_with_buffers_method\b/],
81 |   ];
82 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
83 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/windows_sys/externs.rs: \bfn GetBinaryTypeW\b",
+   "src/windows_sys/externs.rs: \bfn CreateJobObjectW\b",
+   "src/windows_sys/externs.rs: \bstruct WinsockError\b",
+   "src/windows_sys/externs.rs: \bWSA_QOS_ESHAPERATEOBJ\b",
+   "src/mimalloc_sys/mimalloc.rs: \bfn mi_stats_print\b",
+   "src/mimalloc_sys/mimalloc.rs: \bfn mi_reserve_huge_os_pages_interleave\b",
+   "src/mimalloc_sys/mimalloc.rs: \bfn mi_heap_recalloc_aligned_at\b",
+   "src/mimalloc_sys/mimalloc.rs: \bfn mi_wdupenv_s\b",
+   "src/zlib_sys/win32.rs: \bfn gzprintf\b",
+   "src/zlib_sys/win32.
... (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-pub-exports-sweep.test.ts
bun test v1.4.0 (a9da3237f)

test/internal/source-lints/dead-symbols-pub-exports-sweep.test.ts:
(pass) dead FFI declarations (sys crates) do not reappear [37.66ms]
(pass) dead Rust symbols (bun_core, jsc, test_runner) do not reappear [9.84ms]
(pass) orphaned files stay deleted [566.74ms]
(pass) dead JS/codegen helpers do not reappear [56.45ms]
(pass) stale commented-out C++ blocks stay deleted [22.77ms]

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

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 658ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/133] gen ErrorCode+*.h
[2/133] gen generated_host_exports.rs
generated_host_exports.rs: 94 exports (host=3, lazy=10, generic=81, rust=0); 239 extern-C blocks audited
[3/133] gen ZigGeneratedClasses.{cpp,h,rs}
Found 2 classes from /workspace/bun/src/jsc/resolve_message.classes.ts
  - ResolveMessage (13 fields)
  - BuildMessage (10 fields)
Found 1 classes from /workspace/bun/src/runtime/api/Archive.classes.ts
  - Archive (4 fields, 1 class fields)
Found 2 classes from /workspace/bun/src/runtime/api/BunObject.classes.ts
  - ResourceUsage (8 fields)
  - Subprocess (20 fields)
Found 1 classes from /workspace/bun/src/runtime/api/cron.classes.ts
  - CronJob (5 fields)
Found 3 classes from /workspace/bun/src/runtime/api/filesystem_router.classes.ts
  - FileSystemRouter (5 fields)
  - FrameworkFileSystemRouter (2 fields)
  - MatchedRoute (8 fields)
Found 1 classes from /workspace/bun/src/runtime/api/Glob.classes.ts
  - Glob (5 fields)
Found 1 classes from /workspace/bun/src/runtime/api/h2.classes.ts
  - H2FrameP
... (truncated)
diff hotspot
package.json                                       |   1 -
 scripts/build/error.ts                             |  13 -
 scripts/build/flags.ts                             |  39 +-
 scripts/build/source.ts                            |   8 -
 src/ast/lib.rs                                     |   2 +-
 src/ast/nodes.rs                                   |   1 -
 src/base64/lib.rs                                  |   2 +-
 src/boringssl/lib.rs                               |   8 +-
 src/boringssl_sys/boringssl.rs                     |  12 +-
 src/brotli/lib.rs                                  |   4 +-
 src/brotli_sys/brotli_c.rs                         |  47 +-
 src/bun_alloc/lib.rs                               |  10 +-
 src/bun_core/Global.rs                             |   2 +-
 src/bun_core/env.rs                                |   6 +-
 src/bun_core/fmt.rs                                |  14 +-
 src/bundler/HTMLScanner.rs                         |   2 +-
 src/bundler_jsc/PluginRunner.rs                    |   4 -
 src/cares_sys/c_ares.rs                            | 126 +---
 src/codegen/generate-classes.ts                    |  33 --
 src/codegen/generate-js2native.ts                  |   4 -
 src/codegen/helpers.ts                             |  10 -
 src/codegen/replacements.ts                        |  10 -
 src/collections/array_hash_map.rs                  |   4 +-
 src/crash_handler/lib.rs                           |   8 +-
 src/event_loop/MiniEventLoop.rs                    |   4 +-
 src/fallback.html                                  |  28 -
 src/favicon.png                                    | Bin 7804 -> 0 bytes
 src/fixtures_example.com.html                      |  50 --
 src/glob/GlobWalker.rs                             |   4 +-
 src/http/lib.rs                                    |   6 +-
 src/install/lib.rs                                 |   8 +-
 src/install/lockfile.rs                            |   4 +-
 src/install/resolvers/fold
... (truncated)

gate history · 3 passed · 1 rejected · iteration 3

evidence per changed file
file                            reads  edits  tests
package.json                        0      0      0
scripts/build/error.ts              0      0      0
scripts/build/flags.ts              0      0      0
scripts/build/source.ts             0      0      0
src/ast/lib.rs                      0      0      0
src/ast/nodes.rs                    1      1      0
src/base64/lib.rs                   4      4      0
src/boringssl/lib.rs                1      1      0
src/boringssl_sys/boringssl.rs      1      2      0
src/brotli/lib.rs                   0      0      0
src/brotli_sys/brotli_c.rs          1      2      0
src/bun_alloc/lib.rs                1      1      0
src/bun_core/Global.rs              0      0      0
src/bun_core/env.rs                 1      1      0
src/bun_core/fmt.rs                 1      2      0
src/bundler/HTMLScanner.rs          0      0      0
(+ 110 more files)