Conversation
…ckets, and llhttp Relinking the debug binary with --gc-sections --print-gc-sections lists every function nothing references at link time. The ones below also have no textual references outside their own declaration and definition and are not removed by any open PR, so they are deleted together with their declarations and Rust-side FFI wrappers. node:crypto: keyFromString, passphraseFromBufferSource, the header overloads of parseKeyFormat/parseKeyType, ByteSource::fromBIO/foreign, Rsa::encrypt/decrypt with the RSA_Cipher template and setRsaMgf1Md, Cipher::ForEach and its helpers, checkScryptParams, scrypt, pbkdf2, X509View::ifRsa/ifEc, BignumPointer::isOne, BIOPointer::NewFp. JSC/WebCore bindings: the per-request InspectorHTTPServerAgent notifications, ScriptExecutionContext::ensureOnMainThread and executionContext(), JSCStackTrace::getStackTraceForThrownValue, JSCStackFrame::typeName, PerformanceResourceTiming::create and the helpers only it used, rejectPromiseWithGetterTypeError and the never-instantiated RejectPromise branch of IDLAttribute::get, JSErrorHandler (whole files), the callback-interface toJS overloads, and the JSBuffer DOMJIT alloc operations whose signatures were removed in #9457. uSockets: unused accessors (us_socket_is_tls, us_socket_detach, us_socket_pair, us_socket_open, us_listen_socket_ext/port/get_fd, us_socket_group_next/timestamp, us_loop_iteration_number, us_poll_ext, us_connecting_socket_get_loop, the UDP local-ip accessor, several QUIC accessors and the never-set on_open callback) and their Rust wrappers. llhttp: the __wasm__-only block and the getter/name/reset/settings_init API that the HTTP parser bindings never call. Rust: four env vars whose readers were not carried over from the Zig sources, and unused re-exports in node_fs. A source lint pins every removed symbol.
WalkthroughRemoved unused public APIs, internal helpers, FFI bindings, and implementations across uSockets, QUIC, crypto, JSC, WebCore, llhttp, filesystem, and environment-variable code. Added source-lint checks to prevent removed symbols from returning. ChangesDead API cleanup
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
|
Status (head f0bbd11, plus an empty re-run commit c75475c): ready for a maintainer once build 92131 finishes.
|
There was a problem hiding this comment.
I reviewed this PR and found no bugs. Given the breadth — ~1,300 lines removed across 48 files spanning node:crypto, JSC/WebCore bindings, uSockets/QUIC, and llhttp — a human skim would still be worthwhile before merging.
What was reviewed:
- Spot-checked removed uSockets symbols (
us_socket_detach,us_poll_ext,us_socket_pair,us_listen_socket_get_fd,us_loop_iteration_number, SNI userdata, QUICon_open) againstsrc/,packages/bun-uws, and the libuv backend — no remaining callers;sni_node_t::userremoval is safe sinceuseris still stashed on the SSL_CTX ex_data. - Verified
parseKeyFormat/parseKeyTypeThrowScope overloads remain;CastedThisErrorBehavior::RejectPromiseenum value stays forJSDOMOperationReturningPromiseand noIDLAttribute::get<..., RejectPromise>instantiation exists. - Confirmed
JSErrorHandlerhas zero remaining references andus_internal_ssl_detachis still live viaus_internal_socket_close_raw.
Extended reasoning...
Overview
This PR removes ~1,332 lines of provably dead code across 48 files: node:crypto helpers (CryptoUtil.cpp, ncrypto.cpp), JSC/WebCore bindings (ErrorStackTrace, InspectorHTTPServerAgent, ScriptExecutionContext, JSBuffer, JSDOMAttribute, JSErrorHandler, JSAbortAlgorithm, JSPerformanceObserverCallback, PerformanceResourceTiming), the in-tree uSockets fork (TCP/UDP/QUIC accessors, SNI userdata field), llhttp API surface, and Rust FFI wrappers plus unused env-var declarations. Candidates were found via --gc-sections --print-gc-sections on the debug binary, then filtered by textual reference across all source trees and open-PR diffs. A new source-lint test pins every removed symbol.
Security risks
None introduced. Removals touch crypto (ncrypto, CryptoUtil) and TLS SNI (sni_node_t::user), but only delete unreferenced helpers; the live paths (Cipher::encrypt/decrypt, ThrowScope-taking parseKeyFormat/parseKeyType, SSL_CTX ex_data for SNI userdata) are untouched. I verified user is still stored via SSL_CTX_set_ex_data in us_listen_socket_add_server_name, so us_socket_server_name_userdata continues to work.
Level of scrutiny
High, warranting human review. While each individual removal is mechanical and the methodology (linker-driven, cross-referenced against codegen output, all 10 target triples checked) is sound, the aggregate touches critical paths: crypto primitives, JSC GC-sensitive callback wrappers, QUIC connection lifecycle (on_open field/dispatch removed), TLS SNI storage layout, and HTTP parser API. A maintainer familiar with the in-flight work referenced in the description (#33933 uSockets rewrite, #37101, #37149) should confirm none of these are about to gain callers.
Other factors
- Spot-checks against
src/,packages/, and both eventing backends confirm zero remaining callers for a representative sample of removed symbols. - The
CastedThisErrorBehavior::RejectPromisebranch removal fromIDLAttribute::getis safe: the enum value remains forJSDOMOperationReturningPromise, and grep confirms noIDLAttribute::get<..., RejectPromise>instantiation exists. - Only stale references remain in
packages/bun-usockets/misc/manual.md(non-compiled documentation). - The new source-lint test reads
HEADviagit show(matching the siblingdead-code-escapes.test.tspattern) and its regexes correctly use word boundaries so e.g.\\bus_quic_socket_context\\bwon't false-matchus_quic_socket_context_t. - PR description states
bun bdandrust:check-allpass on all targets and lists the test suites run; the test file follows thetest/internal/source-lints/convention.
|
Thanks for the pass. On the two points it leaves for a human:
No open threads. CI build 92078 is in progress (150 jobs green so far, none failed). |
|
This PR may be a duplicate of:
🤖 Generated with Claude Code |
|
Updated 2:49 AM PT - Aug 11th, 2026
✅ @robobun, your commit c75475c6803c652797e4341766e3387eb686d399 passed in 🧪 To try this PR locally: bunx bun-pr 37454That installs a local version of the PR into your bun-37454 --bun |
|
The duplicate-detection bot is right about both overlaps, and they are out of this PR as of 531dbe1:
I also re-diffed the removed lines of this PR against every open PR that touches any of these files (including #37325, #37420, #37427, #37447, #37450 and #37452, which were opened after my first check): there are no other identical deletions, so the rest of the PR is not a duplicate of anything open. The lint and the description are updated to match; the diff is now -1288/+9 in src and packages. CodeRabbit is still rate-limited on this PR, so there is no review from it yet; CI for the new head is build 92093. |
|
Pushed 2877209 for the one claude[bot] finding on 531dbe1 (a doc comment in |
Removing us_quic_pending_connect_user() left us_quic_pending_connect_s::user write-only, so the field, the void *user parameter of us_quic_socket_context_connect, and the argument the h3 client threaded through Context::connect go too. The SSL_CTX ex_data is now the only place SNI userdata is stashed, so its comment no longer says "too".
|
Pushed f0bbd11 for the two claude[bot] findings on 2877209: the pending-connect |
There was a problem hiding this comment.
Both earlier findings are addressed in f0bbd11 (the write-only us_quic_pending_connect_s::user field/parameter chain is gone through to ClientContext::connect, and the stale "too" in the openssl.c SNI comment is dropped); nothing new turned up on this head. Given the breadth (50 files across crypto, JSC/WebCore bindings, uSockets/QUIC, llhttp) and the flagged maintainer call on whether BUN_DUMP_STATE_ON_CRASH should be reimplemented rather than removed, a human look is still warranted.
Checked on this head: the \bus_quic_socket_context\b lint regex does not false-positive on us_quic_socket_context_t/_connect/_on_* (underscore is a word char, no boundary); the updated Context::connect extern signature matches the C definition after the void *user drop; CastedThisErrorBehavior::RejectPromise has no remaining users after its IDLAttribute::get branch was removed.
Extended reasoning...
Overview
Fourth pass on this PR. The head moved from 2877209 to f0bbd11 since my last review; that commit addresses both inline findings I left at 09:00 (the write-only us_quic_pending_connect_s::user field and its parameter chain through quic.h/quic.c/Context.rs/ClientContext.rs, and the dangling "too" in the openssl.c SNI-userdata comment). Commit 00c7d99 also switched the source-lint's symbol checks to read the working tree rather than HEAD, which is orthogonal. The bug-hunting pass on f0bbd11 found nothing.
Security risks
None introduced. Everything removed was already discarded by the linker (--gc-sections --print-gc-sections), so the shipped binary is byte-identical modulo section ordering. The one non-deletion behavior touch — dropping the void *user parameter from us_quic_socket_context_connect — is an FFI signature change I introduced via review; I verified the C definition, header, Rust extern, wrapper, and sole caller all agree on the new arity.
Level of scrutiny
High, because of breadth: 50 files across node:crypto (ncrypto.*, CryptoUtil.*), JSC/WebCore bindings (Buffer DOMJIT ops, JSErrorHandler, IDLAttribute, ScriptExecutionContext, PerformanceResourceTiming), the in-tree uSockets fork (TCP/UDP/QUIC/SNI), llhttp, and Rust FFI wrappers. Each individual hunk is a mechanical deletion, but the interaction with ~open PRs and the one flagged product decision (BUN_DUMP_STATE_ON_CRASH — its reader was never ported from Zig, so removing the declaration vs. reimplementing the feature is a maintainer call the author explicitly deferred) push this past the auto-approve bar.
Other factors
The author's own status comment says "ready for a maintainer once build 92103 finishes" and flags the env-var hunk as needing a human call. CI on the code-identical predecessor 531dbe1 was 160/160 green when superseded; f0bbd11's build 92122 is in flight. All three of my prior findings across earlier heads have been fixed; there are no open threads I'm aware of beyond the two 09:00 inline comments this head resolves.
|
Thanks, agreed on the human look: the current state is summarized in the status comment at the top (head f0bbd11, no open threads, build 92122 in progress), and the one item that is a judgment call rather than a leftover is the |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/bun-usockets/src/crypto/openssl.c (1)
2960-2969: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winStore SNI userdata per registration.
useris documented as per-domain data, but this code stores it in oneSSL_CTXslot. If one context serves multiple hostnames, the last registration makes every hostname use the sameHttpRouter. A duplicate registration can also overwrite the slot beforesni_addrejects it. Storeuserwith the SNI entry, or enforce a one-context/one-user invariant before the write.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/bun-usockets/src/crypto/openssl.c` around lines 2960 - 2969, Update the SNI registration flow around sni_add so the per-domain user value is stored on each SNI node/entry rather than unconditionally in the shared SSL_CTX ex-data slot. Ensure duplicate hostname registration cannot overwrite existing userdata before sni_add rejects it, while preserving the existing rollback via sni_node_destructor and return value.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/bun-usockets/src/crypto/openssl.c`:
- Around line 2960-2969: Update the SNI registration flow around sni_add so the
per-domain user value is stored on each SNI node/entry rather than
unconditionally in the shared SSL_CTX ex-data slot. Ensure duplicate hostname
registration cannot overwrite existing userdata before sni_add rejects it, while
preserving the existing rollback via sni_node_destructor and return value.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ec504994-1266-400e-9a6a-bf0e8116a5e9
📒 Files selected for processing (50)
packages/bun-usockets/src/bsd.cpackages/bun-usockets/src/context.cpackages/bun-usockets/src/crypto/openssl.cpackages/bun-usockets/src/eventing/epoll_kqueue.cpackages/bun-usockets/src/internal/networking/bsd.hpackages/bun-usockets/src/libusockets.hpackages/bun-usockets/src/loop.cpackages/bun-usockets/src/node_quic_shim.cpackages/bun-usockets/src/quic.cpackages/bun-usockets/src/quic.hpackages/bun-usockets/src/socket.cpackages/bun-usockets/src/udp.csrc/bun_core/env_var.rssrc/http/h3_client/ClientContext.rssrc/jsc/bindings/ErrorStackTrace.cppsrc/jsc/bindings/ErrorStackTrace.hsrc/jsc/bindings/InspectorHTTPServerAgent.cppsrc/jsc/bindings/InspectorHTTPServerAgent.hsrc/jsc/bindings/JSBuffer.cppsrc/jsc/bindings/JSDOMExceptionHandling.cppsrc/jsc/bindings/JSDOMExceptionHandling.hsrc/jsc/bindings/ScriptExecutionContext.cppsrc/jsc/bindings/ScriptExecutionContext.hsrc/jsc/bindings/ncrypto.cppsrc/jsc/bindings/ncrypto.hsrc/jsc/bindings/node/crypto/CryptoUtil.cppsrc/jsc/bindings/node/crypto/CryptoUtil.hsrc/jsc/bindings/node/http/llhttp/api.csrc/jsc/bindings/node/http/llhttp/llhttp.hsrc/jsc/bindings/webcore/EventEmitter.cppsrc/jsc/bindings/webcore/EventTarget.cppsrc/jsc/bindings/webcore/JSAbortAlgorithm.cppsrc/jsc/bindings/webcore/JSAbortAlgorithm.hsrc/jsc/bindings/webcore/JSDOMAttribute.hsrc/jsc/bindings/webcore/JSErrorHandler.cppsrc/jsc/bindings/webcore/JSErrorHandler.hsrc/jsc/bindings/webcore/JSPerformanceObserverCallback.cppsrc/jsc/bindings/webcore/JSPerformanceObserverCallback.hsrc/jsc/bindings/webcore/PerformanceResourceTiming.cppsrc/jsc/bindings/webcore/PerformanceResourceTiming.hsrc/jsc/bindings/webcore/ResourceTiming.cppsrc/jsc/bindings/webcore/ResourceTiming.hsrc/lsquic_sys/lib.rssrc/runtime/node/node_fs.rssrc/uws_sys/ListenSocket.rssrc/uws_sys/SocketGroup.rssrc/uws_sys/quic/Context.rssrc/uws_sys/quic/Socket.rssrc/uws_sys/us_socket_t.rstest/internal/source-lints/dead-symbols-linker-sweep.test.ts
💤 Files with no reviewable changes (41)
- src/jsc/bindings/webcore/JSDOMAttribute.h
- packages/bun-usockets/src/udp.c
- src/bun_core/env_var.rs
- src/jsc/bindings/webcore/ResourceTiming.h
- src/jsc/bindings/webcore/EventEmitter.cpp
- src/jsc/bindings/webcore/JSAbortAlgorithm.cpp
- src/jsc/bindings/InspectorHTTPServerAgent.h
- packages/bun-usockets/src/eventing/epoll_kqueue.c
- src/jsc/bindings/webcore/PerformanceResourceTiming.h
- packages/bun-usockets/src/internal/networking/bsd.h
- src/jsc/bindings/webcore/JSAbortAlgorithm.h
- src/jsc/bindings/JSDOMExceptionHandling.cpp
- src/jsc/bindings/webcore/JSErrorHandler.h
- packages/bun-usockets/src/loop.c
- src/lsquic_sys/lib.rs
- src/jsc/bindings/JSDOMExceptionHandling.h
- src/uws_sys/us_socket_t.rs
- src/jsc/bindings/node/http/llhttp/llhttp.h
- src/jsc/bindings/webcore/JSErrorHandler.cpp
- packages/bun-usockets/src/node_quic_shim.c
- packages/bun-usockets/src/bsd.c
- packages/bun-usockets/src/socket.c
- src/jsc/bindings/webcore/ResourceTiming.cpp
- src/jsc/bindings/webcore/EventTarget.cpp
- src/jsc/bindings/ScriptExecutionContext.cpp
- packages/bun-usockets/src/context.c
- src/jsc/bindings/ErrorStackTrace.h
- src/jsc/bindings/webcore/PerformanceResourceTiming.cpp
- src/jsc/bindings/ErrorStackTrace.cpp
- src/jsc/bindings/webcore/JSPerformanceObserverCallback.h
- src/jsc/bindings/node/crypto/CryptoUtil.cpp
- src/jsc/bindings/node/crypto/CryptoUtil.h
- src/uws_sys/SocketGroup.rs
- src/jsc/bindings/ncrypto.h
- src/jsc/bindings/JSBuffer.cpp
- src/jsc/bindings/ncrypto.cpp
- packages/bun-usockets/src/libusockets.h
- src/jsc/bindings/node/http/llhttp/api.c
- src/jsc/bindings/webcore/JSPerformanceObserverCallback.cpp
- src/jsc/bindings/ScriptExecutionContext.h
- src/jsc/bindings/InspectorHTTPServerAgent.cpp
|
On CodeRabbit's one note (the SNI userdata living in the SSL_CTX ex_data slot, No open threads. Build 92131 (the re-run after an unrelated |
|
Heads up on the |
… and misc crates (#39574) ### Problem - `src/jsc/bindings/libuv/` is only on the include path for non-Windows builds (`scripts/build/flags.ts`, "libuv stubs for unix"). `uv/win.h` (703 lines) and `uv/tree.h` (512 lines, included only by `win.h`) are never reached. - `uv/sunos.h`, `uv/os390.h`, `uv/aix.h` and `uv/posix.h` are selected by `uv/unix.h` only on Solaris, z/OS, AIX, IBM i, Cygwin, Haiku, QNX and Hurd. Bun builds for linux, macOS and FreeBSD. - `packages/bun-error` is embedded in the dev error page (`src/runtime/server/dev-error-page.html`). The page calls the function behind `Symbol.for("Bun__renderFallbackError")` and nothing else. `renderRuntimeError`, the abort state `dismissError` kept for it, and the two modules only it imported (`sourcemap.ts`, `stack-trace-parser.ts`) have no callers. #37081 lists this path as a follow-up. - `bun_zlib_sys::posix` and `bun_zlib_sys::win32` declare zlib functions that nothing calls. `bun_zlib` declares its own. The only use of the two modules was as re-exports of the types in `shared.rs`. - A set of `pub` items in other crates has no user in any crate. rustc cannot report them because `pub` items count as used. ### Fix - Delete the six libuv headers. `uv.h` now includes `uv/unix.h` directly. `uv/unix.h` keeps the linux, darwin and BSD branches. `uv-posix-polyfills.c` drops the commented-out copies of the removed branches. - Delete `renderRuntimeError`, `sourcemap.ts` and `stack-trace-parser.ts`. `dismissError` keeps the part that removes the overlay. `runtime-error.ts` stays (it has a test). - Delete `bun_zlib_sys/posix.rs` and `win32.rs`. `bun_zlib` imports the types from `bun_zlib_sys::shared`, which is where the removed modules took them from. - Delete the unused Rust items listed below, plus the trait implementations and imports that only they needed. Verification: - Every Rust item was found by making the unexported items crate-private and compiling the workspace. An item is deleted only if rustc reports it dead on x86_64 linux (dev, release, and with the `bun_debug` and `bun_asan` cfgs), aarch64 linux, x86_64 musl, x86_64 Windows and aarch64 macOS. - Each removed name was also searched in `src/codegen/`, the `*.classes.ts` files, `src/js/` and the C++ bindings. Items that a codegen template can emit were kept. - `bun run rust:check-all`: 12 of 12 targets pass. `cargo check --workspace --all-targets` passes (benches and unit tests still compile). `cargo check -p bun_shim_impl --features shim_standalone` for the Windows target passes. - `bun bd` builds. The build recompiles `uv-posix-stubs.c` and `uv-posix-polyfills.c` against the trimmed `uv.h`, and rebuilds the bun-error bundle, which no longer exports `renderRuntimeError`. - New test in `test/js/bun/http/serve.test.ts`: it takes the bun-error bundle out of a real 500 page, evaluates it outside a browser, and checks that the bundle registers the renderer and that `dismissError` is a no-op when nothing is rendered. This is the surface the `packages/bun-error` change touches. - `bun bd test` passes for `test/js/bun/http/serve.test.ts -t "dev error page"` (including the new test), `test/js/bun/runtime-error.test.ts`, `test/js/bun/util/{zstd,arraybuffersink,filesink}.test.ts`, `test/js/node/zlib/deflate-streaming.test.ts`, `test/js/web/encoding/text-{encoder,decoder}.test.*`, `test/js/workerd/html-rewriter.test.js`, `test/js/bun/css/nth-anplusb-ident.test.ts`, `test/js/web/fetch/blob.test.ts` and `test/internal/source-lints/dead-code-escapes.test.ts`. - `cargo fmt --check`, clang-format on the touched C file and prettier on the touched TypeScript files pass. <details> <summary>Removed Rust items</summary> - `bun_zlib_sys`: modules `posix` and `win32` (`struct_gz_header_s`, `gz_header`, `gz_headerp`, `in_func`, `out_func`, and the `deflate*`, `inflate*`, `compress*`, `uncompress`, `adler32`, `crc32`, `zlibVersion` declarations), `shared::voidpf`. - `bun_zlib`: declarations `compress`, `compressBound`, `uncompress`, and the `internal` module that selected between the two removed modules. - `bun_zstd`: `decompress` (every caller uses `decompress_append`). - `bun_libdeflate_sys`: `libdeflate_deflate_decompress` (the `_ex` variant is the one in use). - `bun_mimalloc_sys`: `mi_strdup`, `mi_heap_collect`, `mi_thread_set_in_threadpool`. - `bun_cares_sys`: `ares_strerror`. - `bun_windows_sys`: `SetHandleInformation`, `closesocket`. - `bun_alloc`: `default_alloc::calloc`. - `bun_core`: `GenericIndexInt::from_usize` and its macro-generated implementations. - `bun_css`: the four deprecated `to_css` methods on `GenericSelectorList`, `GenericSelector`, `GenericComponent` and `Combinator`. Their bodies were `unreachable!()`; the serializer functions replaced them. - `bun_runtime`: `JsSinkType::done` and its six overrides, `FileCloser::update` and its implementations, `ReadableStream::to_js`, `node_fs::Null::to_js`. </details> <details> <summary>Overlap with open pull requests</summary> The deletions here were checked against the open dead-code pull requests (#35437, #35775, #35880, #36115, #36237, #37012, #37149, #37181, #37208, #37301, #37454, #37659, #37788, #38005, #38900, #39319, #39561) and against #38958 and #35075. Nothing deleted here is deleted by any of them. Candidates they already cover were left out: `src/jsc/bindgen.rs` (#37149), the dead `pub use` re-exports (#39319), the simdutf big-endian and UTF-32 wrappers (#38958), and the items named in the skip lists of the others. Some files here (`bun_alloc/lib.rs`, `bun_core/util.rs`, `libdeflate.rs`, `mimalloc.rs`, `node_fs.rs`, `Blob.rs`, `FileSink.rs`, `ReadableStream.rs`, `streams.rs`, `windows_sys/externs.rs`) are also touched by open pull requests in different hunks. #36437 edits `packages/bun-error` from a base that predates #37081; it changes one import line in `stack-trace-parser.ts` and keeps `renderRuntimeError`, so it does not overlap with this deletion but will need a rebase. </details> <details> <summary>Found but not deleted (judgment calls for a maintainer)</summary> - `packages/bun-inspector-protocol/src/protocol/v8/` (about 32,600 lines): not exported by the package index since 2023 and regenerated only with the opt-in `--v8` flag of `scripts/generate-protocol.ts`. #39110 kept the flag, so this needs a decision. - `packages/h3blast` (1,468 lines) and `packages/bun-build-mdx-rs` (558 lines): nothing in the repository references them. They may be kept on purpose as a load generator and a proof of concept. - `packages/bun-error/runtime-error.ts` is unused by the page but covered by `test/js/bun/runtime-error.test.ts`. The four images in `packages/bun-error/img/` are referenced only by the source glob in `scripts/glob-sources.ts`. - `HotReloadTaskView` in `src/jsc/hot_reloader.rs`: both `reload` implementations ignore the task, and `VirtualMachine::reload` ignores its `Option<HotReloadTask>` argument. Removing the plumbing is a small refactor rather than a deletion. - `react_compiler/compile_result.rs` has constructors and fields with no users, but the file says the types are waiting to be wired up. - The streams-era private globals in `BunBuiltinNames.h` (`makeGetterTypeError`, `makeDOMException`, `addAbortAlgorithmToSignal`, `removeAbortAlgorithmFromSignal`, `isAbortSignal`, `createUninitializedArrayBuffer`, about 100 lines of `ZigGlobalObject.cpp`) have no JS callers. Both files are being edited by several open dead-code pull requests, so they were left for a later run. </details> ### Background - rustc's `dead_code` lint treats every `pub` item in a library crate as used, because another crate could import it. In this workspace every crate is an implementation detail of one binary, so a `pub` item with no importer in any crate is dead in the same sense as a private one. Making such items crate-private for one compile lets rustc report the ones with no users at all. The visibility changes themselves are not part of this pull request. - On POSIX, bun does not link libuv. Node-API addons that reference libuv symbols get `uv-posix-stubs.c` and `uv-posix-polyfills*.c`, which are compiled against the copied headers in `src/jsc/bindings/libuv/`. On Windows the real libuv is linked and that directory is not used. - `JsSinkType` is the Rust trait behind the native sink classes (`FileSink`, `ArrayBufferSink`, the HTTP response sinks). Its methods are called from the shared sink glue in `Sink.rs`; `done` was declared there but the glue never called it. <!-- robobun:evidence:begin --> --- **no test proof** · iteration 1 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/js/bun/http/serve.test.ts <!-- robobun:evidence:end -->
|
Closing as stale: this has merge conflicts with main. If the dead code is still present, please open a fresh PR against current main. |
…ockets, and the builtin-name tables (#38900) Removes 775 lines that nothing references (8 lines of signature, import and comment adjustments added), across node:http2, the HTTP/2 frame parser, the JSC/WebCore bindings, uSockets, four Rust crates, the builtin-name tables and scripts/. No behavior change. A 153-line source lint pins every removed symbol. ### Problem - `src/js/node/http2.ts` binds every entry of `constants` as a local (`const { ... } = constants;`); 178 of the 240 bindings have been unused since the block was added in #14286 (every call site reads `constants.X`). `const Socket = net.Socket` and the `#url` / `#isServer` fields of `ServerHttp2Session` are never read either (`tsc --noUnusedLocals`, re-checked by grep). - `_nativeAssertSettings` (`$newRustFunction("h2_frame_parser.rs", "jsAssertSettings")`) has been unused since #28074 gave http2.ts its own `assertSettings()`. That made `js_assert_settings` in `src/runtime/api/bun/h2_frame_parser.rs` (139 lines) and its facade re-export in `src/runtime/api.rs` unreachable: the js2native codegen was the only thing that named it. The three `BUN_DECLARE_HOST_FUNCTION(BUN__HTTP2_*)` lines in `ZigGlobalObject.cpp` are declarations of the Zig-era exports for the same helpers and have no definition anywhere. - `InspectorHTTPServerAgent::{startListening, stopListening, getRequestBody, getResponseBody}` are TODO stubs that nothing can dispatch to: the generated `HTTPServerBackendDispatcherHandler` in the pinned WebKit only declares `enable()` / `disable()`, so these `virtual ... final` methods override nothing and have no callers. - Declaration-only leftovers with no definition anywhere: `Bun__DNSResolver__new` / `Bun__DNSResolver__cancel` (`BunObject.cpp`), `jsBufferConstructorFunction_isBuffer` (`JSBuffer.cpp`, `Buffer.isBuffer` is a JS builtin), `getStringOption` (`CryptoUtil.h`). Plus the `IsIDLEnumeration` helper template (`IDLTypes.h`) and the `globalBuiltinFunction` macro (`ZigGlobalObject.cpp`), each with zero uses. - uSockets: `us_internal_ssl_sni_userdata` and `us_internal_ssl_handshake_abort` were added in #29932 and never called (`us_socket_server_name_userdata`, which the first one wrapped, stays). `us_cleanup_security_framework` (darwin) had no caller; the loader's failure paths are the only thing that ever frees a `SecurityFramework`, and they still do. The `SecTrustSettingsResult` typedef next to it was unused too. - Rust items no crate reaches (hawk `dead_public`, intersected over linux-gnu, linux-musl, android, freebsd, darwin and windows-msvc, then re-checked by hand): `ExprData::is_e_string`, `ArrayHashMap::get_adapted`, the debug-only `Behavior::eq`, and `js_parser::FunctionKind`, whose `Stmt` variant was never constructed. `validate_function_name` only ever ran for function expressions, so the parameter is gone and the one call site passes nothing; the error text already said "function expression". - Builtin-name tables: `Loader`, `byobRequest`, `controller`, `post`, `resume`, `started`, `state`, `textDecoder` and `view` in `BunBuiltinNames.h` have no `$name` / `@name` use in any builtin and no `namePublicName()` / `namePrivateName()` use in C++ (each entry costs two identifiers at VM startup). Their `builtins.d.ts` declarations go with them, as do the six `$stream*` `--define`s in `replacements.ts` (no builtin reads them; their only trace was the `.d.ts`), the `"Loader"` entry of `globalsToPrefix` (the only bare `Loader` in src/js is inside a block comment), and a duplicated `"Buffer"` entry. - `scripts/find-dead-exports.ts` (303 lines, #31254) was a textual approximation of the analysis `tools/hawk/` + `hawk.toml` now do (#36184); nothing references it. ### Fix - Deletes the items above; the only additions are the shorter `validate_function_name` signature, one comment in `semver/lib.rs` that named `get_adapted` (now names the surviving `get_index_adapted`), and the re-export line in `api.rs`. - Removing the `$newRustFunction` call is what makes the Rust function removable: `generate-js2native.ts` emits the `crate::api::bun::h2_frame_parser::js_assert_settings` thunk only for calls it finds in src/js, so after this change nothing generated names it either. `bundle-functions.ts` regenerates `BunBuiltinNames+extras.h` from the names builtins actually use, so a builtin-name entry that were still needed would be re-added by the build rather than break it; none was. - Verified: `bun bd` builds; `bun run rust:check-all` passes on all ten target triples; `cargo fmt --check` and prettier are clean. `bun bd test` passes on `test/js/node/http2/node-http2.test.js` (357), `test/js/node/http2/node-http2-continuation.test.ts`, `test/js/node/buffer.test.js`, `test/js/node/crypto/node-crypto.test.js`, `test/js/node/tls/node-tls-connect.test.ts`, `test/js/web/streams/streams.test.js` and `test/bundler/bundler_minify.test.ts`; `test/js/node/tls/node-tls-server.test.ts` passes 69/70, the remaining one (`SNICallback runs even when the requested servername matches the bind hostname`) fails identically with the released binary in this container (it binds `localhost` and connects to 127.0.0.1). The four function-name diagnostics `validate_function_name` emits are unchanged between the released binary and this build for both statement and expression positions. `bun test test/internal/source-lints/` passes (158 tests); the new `dead-symbols-http2-settings-inspector-stubs.test.ts` fails on main and passes here. - Cross-checked against the 22 open dead-code PRs at the symbol level (their diffs, not just file lists): nothing here is removed by any of them. Two hunks are adjacent to open ones and will need a trivial rebase on whichever side lands second: the `BUN__HTTP2_*` lines sit right under the `Bun__NodeUtil__jsParseArgs` line #37788 removes, and the `InspectorHTTPServerAgent` hunks are a few lines above the event dispatchers #37454 removes. One item found dead here, `JSValkeyClient::close_subscription_ctx`, is the renamed form of the `SubscriptionCtx::close` that #38439 already removes, so it was left to that PR. ### Background - js2native: `$rust("file.rs", "name")` / `$newRustFunction(...)` calls in src/js are collected at build time by `src/codegen/generate-js2native.ts`, which emits one thunk per call into `generated_js2native.rs` / `GeneratedJS2Native.h`. A Rust host function is therefore reachable only while some builtin names it; the `api.rs` facade module exists so the generated thunks have a stable path to call. - `BunBuiltinNames.h` is the list of private identifiers (`@name` in builtin JS, `builtinNames.namePrivateName()` in C++) that `BunBuiltinNames` interns when a VM starts. `bundle-functions.ts` diffs the names builtins use against this list and writes the difference to `BunBuiltinNames+extras.h`, which is why removing an entry can only ever remove startup work, never break a builtin. - Inspector agents: the WebKit inspector protocol generator turns each domain's JSON into a `*BackendDispatcherHandler` interface; a command reaches an agent only through that interface. The HTTPServer domain bun ships in its WebKit defines `enable` and `disable`, so methods an agent declares beyond those are unreachable by construction. - hawk (`tools/hawk/README.md`) is the workspace-wide reachability analysis the repo uses for `pub` items, since rustc's `dead_code` treats every `pub` item of a library crate as a root. Its per-target reports were intersected so that anything live under some `cfg` on any shipped platform was kept; the repr(C) FFI struct fields and flag/errno table entries it also reports were left alone on purpose, as in #38703. <details> <summary>Found dead but left alone (follow-ups, not in this diff)</summary> - `bun_sys::ErrorCase::LeakFdOnFail` is never constructed (every `make_lib_uv_owned_for_syscall` caller passes `CloseOnFail`), but removing it means dropping the parameter at 13 call sites, several of them in files open PRs are editing. - `libusockets.h` still declares `us_udp_socket_receive`, `us_udp_buffer_set_packet_payload`, `us_create_udp_packet_buffer` and `us_udp_socket_bind` with no definitions, and `udp.c` carries a commented-out `us_udp_packet_buffer_ecn`; both spots are adjacent to hunks in #37454. - `NapiEnv::currentFinalizer()` became unused in #37075 a week ago; left for that work to settle, as #37454 did with its siblings. - `replacements.ts` also emits a `$ImportKindLabelToId` define nothing reads, but it comes out of the same loop as three live tables. - `ws.js` `WebSocket.prototype.setSocket` (a throwing stub) and `async_hooks` `AsyncResource.emitBefore/emitAfter` have no in-tree users but are on exported classes. - `scripts/packer/build-image.pkr.hcl` and `scripts/trace.sh` have no invoker, but they are CI infrastructure rather than code; flagged for whoever owns those. - Everything else this pass turned up (about 270 C++ symbols and about 100 Rust items) is already deleted by one of the open dead-code PRs, and the roughly 400 never-read Rust fields hawk reports are all repr(C) mirrors of C structs. </details> --------- Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
…uilt-in JS, bindgen, uSockets, and 66 Cargo manifests (#39732) ### Problem - The tree carries code that nothing references: FFI shims with no caller on either side, enum variants that are never constructed, write-only fields, exports that no module imports, and Cargo dependency edges that no source file uses. - 16 dead-code PRs that removed much of this were closed as stale after merge conflicts. Their deletions were never re-applied (list in the notes). ### Fix - Re-apply the deletions that still apply to current main and add new ones in the same areas: `simdutf_sys`, `ncrypto` and the WebCore bindings, `js_parser`, `bundler`, `js_printer`, `bun_install`, built-in JS, bindgen, uSockets, and 66 Cargo manifests. 176 files, +95 / -3129 (`Cargo.lock` is -436 of that). - Every deletion was checked again with `rg` over `src/`, `packages/`, `src/codegen/` and the generated code. Items that became live again since the old PRs stay (examples in the notes). - No deletion duplicates an open dead-code PR. Deletions that need #39618 or #39697 to land first are listed as follow-ups in the notes. - Verified: `bun bd`, `bun run rust:check-all` (12 targets pass), byte-identical bindgen output, `test/internal/source-lints`, and the test files of the touched areas (list in the notes). New tests in `transpiler.test.js` and `bundler_edgecase.test.ts` pin the two diagnostics that `mark_strict_mode_feature` still emits and the class body printing that `visit_class` still does. ### Background - A Rust `extern "C"` declaration with no call site creates no link reference, so a dead FFI chain is removed on both sides at once. Three C++ definitions whose Rust side #39618 removes stay until that PR lands. - `cargo check` covers the host target only. `rust:check-all` repeats it for every shipped target, which proves the `#[cfg]`-gated deletions and the Windows-only dependency removal (`bun_sys` -> `bun_output`). - The dependency removals are manifest-only. `Cargo.lock` loses the matching entries and nothing else: no version changes. <details><summary>Notes</summary> **Closed PRs re-applied**: #35437, #35559, #35775, #35880, #36115, #36237, #37012, #37062, #37089, #37208, #37272, #37454, #37788, #38005, #38439, #38703. **Kept because they are live again on main**: `GenericIndexOptional::{get, is_some, is_none}`, the WebSocket deflate `OutOfMemory` variants, `V8Local::reinterpret`, `SystemErrno::MAX`, `MarkPopErrorOnReturn::peekError`, `ResourceTiming::populateServerTiming`, `UvHandle` in `test/parallel/Channel.rs`, the `h2::FrameType` entries that `hawk.toml` marks as a code table. **Tests run**: node-http, node-http2, fetch headers, streams, readable-stream-blob-consumed, filesink, transpiler, buffer, url, FormData, TextEncoder, MessageChannel, serve-direct-readable-stream, serve-body-leak, crypto key objects, crypto-rsa, scrypt, pbkdf2, sqlite-sql, local-sql, postgres-simple-query-pipeline, sql-helpers-validation, bun-outdated, websocket-server, test/internal (bindgen, codegen outputs, source lints). The `localhost` proxy test in node-http and the concurrent WebSocket send tests fail the same way on unmodified main in this environment (the first is a `localhost` resolution issue, the second is the 300k-message benchmark starving its concurrent neighbours in a debug build). **By kind**: C/C++ -1327, Rust -702 (+75, mostly signature updates at call sites), built-in JS/TS -130, codegen TS -75 (+13), Cargo manifests -459, `Cargo.lock` -436. **simdutf_sys** (`simdutf.rs`, `bun-simdutf.cpp`, `parsers/benches/support/simdutf_shim.cpp`): 16 shim chains with no caller, each removed as Rust wrapper + `extern` declaration + C++ definition: `simdutf__convert_utf8_to_utf16le`, `_utf16be`, `_utf16be_with_errors`, `convert_utf8_to_utf32_with_errors`, `convert_valid_utf8_to_utf32`, `convert_utf16be_to_utf8_with_errors`, `convert_valid_utf16be_to_utf8`, `convert_utf32_to_utf8_with_errors`, `convert_valid_utf32_to_utf8`, `convert_utf32_to_utf16be_with_errors`, `convert_valid_utf32_to_utf16be`, `convert_utf16be_to_utf32_with_errors`, `convert_valid_utf16be_to_utf32`, `utf8_length_from_utf16be`, `utf32_length_from_utf16be`, `utf32_length_from_utf8`, plus the now empty `utf32` modules and the `be` wrappers. **ncrypto** (`ncrypto.h/.cpp`): `BignumPointer::isOne`, `X509View::ifRsa`, `X509View::ifEc`, `BIOPointer::NewFp`, `checkScryptParams`, `scrypt`, `pbkdf2`, `EVPKeyCtxPointer::setRsaMgf1Md`, `Rsa::encrypt`, `Rsa::decrypt` and the `RSA_Cipher` template, `Cipher::ForEach` with `CipherCallbackContext`/`array_push_back`, `NCRYPTO_REQUIRE`, `NCRYPTO_VERSION` and the version enum. **JSC / WebCore bindings**: `ZigGlobalObject`: `functionFulfillModuleSync` (and the `fulfillModuleSync` builtin name plus `$fulfillModuleSync` stub), `JSDOMFileConstructor_getter/_setter`, `navigatorObject`, `functionLazyNavigatorGetter`, `GlobalObject_getPerformanceObject`, `hasNapiFinalizers`, `jsFunctionNotImplemented`, `jsFunctionCreateFunctionThatMasqueradesAsUndefined`, `Zig__GlobalObject__getModuleRegistryMap`/`resetModuleRegistryMap`, `NodeVM*ModulePrototype()` accessors, `ZIG_GLOBAL_OBJECT_DEFINED`. `BunString.cpp`: `Bun__WTFStringImpl__ref`/`deref` definitions (Rust inlines these; #39618 removes the declarations). `JSBuffer.cpp`: the `JSValue`-name `validateOffset` overload and the three unused `jsBufferConstructorAlloc*WithoutTypeChecks` JIT operations. `NodeValidator`: `validateString(JSValue name)` and `validateOneOf(span<ASCIILiteral>)`. `ScriptExecutionContext`: `ensureOnMainThread`, `executionContext`. `napi.h`: `hasFinalizers`, `currentFinalizer`, `isVMTerminating`. `IDLTypes.h`: `IDLDate`, the `NullableTypeWithLessPadding` helpers and two includes. `BunProcess.cpp`: three unused `*CodeGenerator` aliases. `c-bindings.cpp`: `HNS_PER_SEC`, `NS_PER_HNS`, `HNS_PER_US`. `BunCommonStrings.h`: `ConnectionWasClosed`, `ec`, `ed25519`, `rsa`, `rsaPss`, `jwkDsa`, `jwkG`, `systemError`, `x25519`. `BakeAdditionsToGlobalObject.h`: the never-read `m_bakeGetAsyncLocalStorage` lazy property (the function is still installed directly) and the `LazyPropertyOfGlobalObject` alias. `JSBundlerPlugin.cpp`: the `JSBundlerPlugin__onVirtualModulePlugin` declaration, which has no definition. WebCore: `DeferredPromise::whenSettled` and the `PromiseFunction`/`BindingPromiseFunction` adapters, `JSEventListener::sourceURL/sourcePosition`, `Event::receivedTarget`, `toJS(PerformanceObserverCallback)` and `callbackData()`, `jsFetchHeaders_getRawKeys` (its only caller in `internal/http.ts` is removed too), stale forward declarations in `Performance.h`/`ResourceTiming.h`, and the commented-out `BINDING_INTEGRITY` blocks in 8 generated-style files. `node/crypto`: `JSPrivateKeyObjectConstructor` and `JSPublicKeyObjectConstructor` (4 files, superseded by `JSKeyObjectConstructor`). Bake: `BakeRegisterProductionChunk`, `BakeProdSourceMap`, `BakeProduction.h`, the `IncrementalGraph` log scope. **uSockets**: `us_poll_ext`, `us_loop_iteration_number`, `us_socket_is_tls`, `us_connecting_socket_get_loop`, `us_udp_packet_buffer_local_ip` / `bsd_udp_packet_buffer_local_ip`. **Rust**: `js_parser`: the six `StrictModeFeature` variants that are never constructed (and the `can_be_transformed` branch), `FnOnlyDataVisit::{class_name_ref, should_replace_this_with_class_name_ref, is_inside_async_arrow_fn}` with the `this` substitution path that was gated on the always-false flag (the `shadow_ref` arena cell becomes a plain `Ref`). `bundler`: `Linker::{resolver, hashed_filenames}`, `IS_CACHE_ENABLED`, `InputFileFlags::IS_PLUGIN_FILE`, `parse_task::Step::ReadFile`. `js_printer`: the write-only `Options::transform_only`. `bun_install`: `CacheBehavior`/`ManifestLoad` (every caller passed `LoadFromMemoryFallbackToDisk`, so the parameter and the memory-only branch are gone from `by_name`, `by_name_hash` and `by_name_hash_allow_expired`), `pub use patch_install as patch`. `webcore`: `ReadableStream::detach_if_possible` (empty) and the `global` parameter of `done()`, `BlobExt::{on_structured_clone_transfer, get_mime_type}`, six `StartTag` variants that no sink uses. `server`: `AnyRoute::ref_`, the write-only `OPENED_BIT`. `bun_core`: `concat`, `ExternalShared::as_ptr`, `QuoteEscapeFormatFlags::ascii_only`. `bun_io`: stale `Waker`/`Closer` re-exports. `bun_sys`: `UTIME_OMIT`. `cli`: the never-read `IS_MAIN_THREAD` thread local. `css`: `DeclarationContext::Keyframes`, the empty `generated_color_conversions` module. `html_rewriter`: the `EndTag.replace` host function that `html_rewriter.classes.ts` does not expose. **Built-in JS/TS**: `internal/http.ts`: 29 unused symbol constants, `filterEnvForProxies`, `getRawKeys`, `emitCloseNTAndComplete`, `ClientRequestEmitState`. `node/http2.ts`: `kSettingNames`, three unused primordials. `internal/sql/query.ts` and `internal/repl/node-shims.js`: export entries nothing imports, and the `BuiltinModule` shim methods nothing calls. `builtins.d.ts`: 8 stubs for builtin names that no longer exist. **bindgen** (`src/codegen/bindgen*.ts`): `allFunctions`, `ArgStrategyChildItem`, `Variant.argStruct`, `Struct.namespace`/`toString`, `FuncMetadata`/`exposedOn`/`ExposedOn`, `FuncWithoutOverloads`, the dead `debug` binding, two shadowed duplicate `case` labels and an unreachable `return`. Generated output is byte-identical. **Cargo**: 459 dependency lines across 66 manifests (mostly the `strum`/`bstr`/`scopeguard`/`const_format`/`enum-map`/`enumset`/`libc`/`bitflags` boilerplate block, plus 94 `bun_*` edges such as `bun_jsc -> bun_simdutf_sys` and `bun_bundler_jsc -> 8 crates`). One dev-dependency (`bun_router -> bun_js_parser`, checked with `cargo check -p bun_router --tests`). The manifests that #39618 and #39697 already edit (`collections`, `io`, `paths`, `css`, `shell_parser`, `sql`, `sql_jsc`) were left alone. **Rebase note**: main restructured the private builtin function registration in `ZigGlobalObject::addBuiltinGlobals` into a table (#39770). The conflict was resolved by dropping the `k_fulfillModuleSync` row from the new table, which is the same registration the first version of this PR removed. #39770 also touched the two `JS*KeyObjectConstructor.h` files before this PR deletes them; they are still unreferenced on main, so the deletion stands. Re-verified after the rebase: `bun bd`, `rust:check-all` 12/12, and the test files listed above. **Follow-ups once open PRs land** (not done here to avoid duplicating them): after #39618: the C++ definitions of `URL__fromJS` (BunString.cpp) and `Bun__allocUint8ArrayForCopy` (ZigGlobalObject.cpp), the seven `<Sink>()` constructor accessors in `ZigGlobalObject.h` that only the generated `__getter` functions use, the Rust `extern` declarations of `Bun__WTFStringImpl__ref/deref`, and `BufferWriter::append_null_byte` (no writer ever sets it to true). After #39697: the root `[workspace.dependencies] typed-arena` entry. Independently of those: the `DeferredPromise::{promise, resolve(), reject(...)}` overloads and `DOMPromise::whenPromiseIsSettled` have no callers but sit next to code #39618 edits. </details> <!-- robobun:evidence:begin --> --- **no test proof** · iteration 1 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/bundler/bundler_edgecase.test.ts <!-- robobun:evidence:end -->
Removes 1,302 lines of code that nothing references (16 lines added, all import, signature and comment adjustments), across the C++ JSC bindings, node:crypto helpers, the in-tree uSockets fork, llhttp, and a few Rust FFI wrappers. No behavior change: every removed function was discarded by the linker, i.e. the shipped binary never contained it.
How the candidates were found
Previous sweeps were grep-driven, so this run used the linker instead: the debug binary was relinked with
-Wl,--gc-sections -Wl,--print-gc-sectionsand the discarded.text.*sections from bun's own objects (minus anything still present in the output) gave ~4,300 symbols that nothing references at link time. Those were filtered down bysrc/,packages/,scripts/and freshly regeneratedbuild/debug/codegen/(anything mentioned outside its own declaration/definition was read by hand, e.g. for#ifplatform blocks, macro token pasting, Rustexternblocks,.classes.ts/ builtin string references);napi_*,node_api_*,uv_*, thev8::shim,src/symbols.dyn), which is unreferenced by design and was left alone, together with helpers only those reach;JSCStackTrace::getStackTraceForThrownValue, which Error.prepareStackTrace: index source URLs by visible frame, not by JSC frame #37450 removes as part of its fix, were dropped from this PR (a few hunks inncrypto.*are adjacent to Remove dead code from C++ bindings, bindgen glue, ast, and orphaned scripts #37149's, but they delete different functions).On the Rust side every crate was additionally checked by demoting its
pubitems topub(crate)and letting rustc'sdead_codeanalysis run; almost everything it reported was already claimed by open PRs, so only the items below are included.Removed
node:crypto (
CryptoUtil.*,ncrypto.*)keyFromString,passphraseFromBufferSource, and the header overloads ofparseKeyFormat/parseKeyType(theThrowScopeoverloads are the live ones);ByteSource::fromBIO,ByteSource::foreign; theBunString.hinclude they neededRsa::encrypt/Rsa::decryptand theRSA_Ciphertemplate behind them (the live path isCipher::encrypt/decrypt), plusEVPKeyCtxPointer::setRsaMgf1Md, which only they calledCipher::ForEachwith itsCipherCallbackContext/array_push_backhelpers andCipherNameCallbackalias (node_crypto_binding.cppcallsEVP_CIPHER_do_all_sorteddirectly)checkScryptParams,scrypt,pbkdf2(scrypt/pbkdf2 go through the Rust bindings),X509View::ifRsa/ifEcand theirKeyCallbackalias,BignumPointer::isOne,BIOPointer::NewFpJSC / WebCore bindings
InspectorHTTPServerAgent::requestWillBeSent/responseReceived/bodyChunkReceived/requestFinished/requestHandlerException(their Rust callers were removed in an earlier sweep)ScriptExecutionContext::ensureOnMainThread, free functionexecutionContext(JSGlobalObject*)JSCStackFrame::typeName/retrieveTypeName/m_typeName(the neighbouringgetStackTraceForThrownValueis removed by Error.prepareStackTrace: index source URLs by visible frame, not by JSC frame #37450)PerformanceResourceTiming::createand its constructor, theentryStartTime/entryEndTimehelpers, andResourceTiming::populateServerTiming, which only the constructor used (the class is still exposed as a global constructor; nothing ever instantiates it natively)rejectPromiseWithGetterTypeErrorand theCastedThisErrorBehavior::RejectPromisebranch ofIDLAttribute::getthat was its only (never instantiated) userJSErrorHandler.cpp/JSErrorHandler.h(whole files) and thesetAttributeEventListener<JSErrorHandler>instantiation: no attribute listener is ever created with itcallbackData()and the native-to-JStoJS(...)overloads ofJSAbortAlgorithmandJSPerformanceObserverCallback(only the JS-to-native direction is used)JSBuffer.cpp: thejsBufferConstructorAlloc*WithoutTypeChecksDOMJIT operations (their signatures went away in Fix incorrect include order #9457) and theJSValue-namedvalidateOffsetoverloaduSockets (
packages/bun-usockets) and its Rust wrappersus_socket_is_tls,us_socket_detach,us_connecting_socket_get_loop,us_socket_pair(+SocketGroup::pair),us_socket_open(+us_socket_t::open),us_listen_socket_ext,us_listen_socket_port,us_listen_socket_get_fd(+ListenSocket::fd),us_socket_group_next,us_socket_group_timestamp,us_loop_iteration_number(Rust readsiteration_nrfrom the struct directly),us_poll_extus_listen_socket_find_server_name_userdataand the now write-onlysni_node_t::userfield (userdata is looked up through theSSL_CTXex_data byus_socket_server_name_userdata)us_udp_packet_buffer_local_ip/bsd_udp_packet_buffer_local_ipus_quic_pending_connect_usertogether with the now write-onlyuserfield it read and thevoid *userparameter ofus_quic_socket_context_connect/Context::connectthat only fed it, theus_quic_socket_contextaccessor,us_quic_stream_flush,us_quic_stream_has_unacked,us_quic_socket_close(+quic::Socket::close), the never-seton_opencallback (field, setter and dispatch),us_nq_spec_peer_ctx(+ its Rust declaration)llhttp (
src/jsc/bindings/node/http/llhttp, already trimmed in #36576)__wasm__-only block (llhttp_alloc/llhttp_freeand the wasm settings table; bun never builds this file for wasm), thellhttp_get_*accessors,llhttp_reset,llhttp_settings_init,llhttp_method_name,llhttp_status_name,llhttp__debugRust
env_var.rs:BUN_DUMP_STATE_ON_CRASH(bake's crash-state dump;BUN_NEEDS_PROC_SELF_WORKAROUND,MI_VERBOSEandTODIUMare in the same state but already removed by Remove dead code from C++ bindings, src/js builtins, CSS, and Rust util crates #35437). Its reader lived in the Zig sources and was not carried over in the Rust rewrite, so nothing has read it since May; if the feature is wanted back it needs to be reimplemented, not just declared.node_fs.rs: re-exports ofCpSingleTask,IntoResultListEntry,ResultListEntry,ResultListEntryValuethat nothing imported (the items themselves are still used inside the module and becomepub(crate)).test/internal/source-lints/dead-symbols-linker-sweep.test.tspins every removed symbol so it cannot quietly come back; it fails onmainand passes here.Verification
bun bd(full debug build) passes;bun run rust:check-allpasses on all 10 target triples;cargo fmt --checkand clang-format are clean.bun bd testpasses ontest/js/node/crypto/{node-crypto,crypto-rsa,crypto.key-objects,scrypt,pbkdf2,x509},test/js/node/http/node-http-parser.test.ts,test/js/bun/udp/udp_socket.test.ts,test/js/node/quic/quic-stream.test.ts,test/js/web/abort/abort.test.ts,test/js/node/perf_hooks/perf_hooks.test.ts,test/js/node/v8/capture-stack-trace.test.js,test/regression/issue/prepare-stack-trace-crash.test.ts,test/js/node/buffer.test.js, andbun bd test/js/node/test/parallel/test-tls-sni-server-client.jsexits 0.test/js/bun/http/serve.test.tshas the same 4 failures as the released binary in this container (IPv6, privileged ports, non-loopback clients); everything else in it passes.us_socket_detachin a comment as an example of a detach path; that comment can be reworded when it lands.Left alone on purpose (follow-ups, not in this diff)
DOMPromise::whenPromiseIsSettled->DeferredPromise::whenSettledchain (~85 lines) is dead but its last link is removed by Remove dead code from webcore bindings, watcher, node-fallbacks, and misc crates #37062; it can go once that lands.JSPromise::resolve_task/settle_task,VM::has_termination_request+JSC__VM__hasTerminationRequest,Completion::off_thread,JsThread-witness accessors injob.rs) are left for that work to settle.ServerTiming.h/.cpp,ResourceTiming's constructor andPerformanceServerTiming::createare now only reachable from each other; removing them means deciding what to do with the still-exposedPerformanceServerTimingconstructor.<Class>_gettercustom getters that theFOR_EACH_...macro inZigGlobalObject.cppemits for ~40 classes that never install them are discarded by the linker; dropping them needs the macro split, not a deletion.PerformanceResourceTimingitself,sqlite3.c's RBU/session extensions, and the Loose/ClampJSDOMConvertNumbersinstantiations are unreferenced but are either exposed API surface, vendored, or supported generator options.[review] gate passed · iteration 1 · 50 files touched
fails on main (without fix)
passes on PR (with fix)
diff hotspot
gate history · 1 passed · 1 rejected · iteration 1
evidence per changed file