Skip to content

Remove dead code from the WebCore bindings, the JSSink codegen, and two Rust helpers - #39929

Open
robobun wants to merge 6 commits into
mainfrom
claude/farm/7f50dbf5/dead-code-cpp-link-sweep
Open

robobun wants to merge 6 commits into
mainfrom
claude/farm/7f50dbf5/dead-code-cpp-link-sweep

Conversation

@robobun

@robobun robobun commented Aug 21, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • The WebCore-derived bindings define functions that nothing calls. A link-level reachability pass over the debug objects reports them unreachable, and rg finds only the definition and the declaration.
  • Some items exist only in headers, which a link pass cannot see: accessors that a macro expands per HTTP header name and per markdown tag, the Set flavour of JSDOMIterator, and FetchHeaders guard helpers.

Fix

  • Delete the toWrapped() static of 17 wrapper classes and the reference taking toJS(..., T&) overload of 11 types.
  • Delete leaf functions: DeferredPromise::promise() and four reject() overloads, unused Event, ErrorEvent and CustomEvent constructors, and a few more. The Notes list every symbol.
  • Delete the header-only items, the construct() method that generate-jssink.ts emitted for every sink, and two Rust items that hawk reports (PluginRunner::could_be_plugin in bun_jsc, PathSeparators::POSIX).
  • Verified: bun bd builds, bun bd test on 22 files that use the touched classes passes (1202 pass, 0 fail), and CI built every platform. New tests in arraybuffersink.test.ts and FormData.test.ts pin the sink constructor and the FormData iteration that the edited codegen and JSDOMIterator.h produce. They pass before and after this change: a deletion of unreachable code has no behaviour a test can fail on, and the repo does not want tests that assert a symbol is absent (test/internal/source-lints/CLAUDE.md). Each deletion removes the declaration too, so a caller on another platform fails to compile, not to link.

Background

Notes: removed symbols, verification, what was left for later

Removed, C++ (definition and declaration in each case):

  • toWrapped() of JSAbortController, JSCookieMap, JSDOMFormData, JSDOMURL, JSEventEmitter, JSFetchHeaders, JSMessageChannel, JSPerformanceEntry, JSPerformanceObserver, JSPerformanceObserverEntryList, JSPerformanceServerTiming, JSPerformanceTiming, JSTextEncoder, JSURLPattern, JSURLSearchParams, JSWasmStreamingCompiler, JSWebSocket. JSCookieMap.cpp and JSWasmStreamingCompiler.cpp also lose the file-local toWrapped(JSGlobalObject&, ExceptionThrower&&, JSValue) templates that only named the deleted statics.
  • toJS(..., T&) and the inline toJS(..., T*) forwarder for AbortController, CloseEvent, CookieMap, CustomEvent, DOMFormData, ErrorEvent, MessageChannel, TextEncoder, URLPattern and JSC::Wasm::StreamingCompiler.
  • DeferredPromise::promise(), DeferredPromise::reject(RejectAsHandled), reject(std::nullptr_t, RejectAsHandled), reject(JSValue, RejectAsHandled), reject(const PrivateName&, RejectAsHandled). All live callers use the Exception and ExceptionCode overloads.
  • Event::Event(EventInterface, IsTrusted), the seven argument Event::Event(..., MonotonicTime, IsTrusted), the two ErrorEvent constructors that take a message and a file name plus the two inline create() overloads that were their only users (every caller uses the Init overload), CustomEvent::create(IsTrusted) and the private constructor behind it.
  • HTTPHeaderMap::remove(StringView), JSEventListener::functionName(), URLPattern::create(ScriptExecutionContext&, Compatible&&, const String&) and the Compatible alias, JSReadableStreamAsyncIterator::prototype(), JSWasmStreamingCompiler::prototype(), JSNodeHTTPServerSocket::create(VM&, Zig::GlobalObject*, us_socket_t*, bool, JSNodeHTTPResponse*), JSBakeResponse::createStructure() (instances use createJSBakeResponseStructure), Bun::createError(JSGlobalObject*, ErrorCode, JSValue) and the declaration-only createError(Zig::GlobalObject*, ErrorCode, JSValue) in ErrorCode.h.
  • Header only: HTTP_HEADERS_ACCESSOR_DEFINITIONS and the Index taking identifierAt/stringAt overloads in HTTPHeaderIdentifiers.h (none of the 99 <name>Identifier() / <name>String() accessors had a caller, callers use identifierFor/stringFor), MARKDOWN_TAG_STRINGS_ACCESSOR_DEFINITION in BunMarkdownTagStrings.h (none of the 30 accessors had a caller, Rust goes through stringAt), the Set flavour of JSDOMIterator.h (all four iterator traits in the tree are Map): the Set asJS and appendForEachArguments, and with them the JSDOMIteratorType enum, EnableIfMap/EnableIfSet, the type member of the four traits structs and the <type_traits> include; the three includes that only the removed ErrorEvent constructors used (Strong.h in ErrorEvent.h, EventNames.h and StrongInlines.h in ErrorEvent.cpp); FetchHeaders::setGuard(), FetchHeaders::guard() and the EnumTraits<FetchHeaders::Guard> specialization, both JSEventListener::wasCreatedFromMarkup overloads together with the m_wasCreatedFromMarkup bit they read, the CreatedFromMarkup enum, the constructor parameter that fed it and the two CreatedFromMarkup::No call sites (JSEventListener.cpp, JSErrorHandler.cpp), and the OperationFailed and OperationTimedOut entries of BunCommonStrings.h.
  • src/codegen/generate-jssink.ts: the per-sink ${constructor}::construct declaration and definition.

Removed, Rust: PluginRunner::could_be_plugin (src/jsc/PluginRunner.rs, callers use the bun_bundler one) and PathSeparators::POSIX (src/paths/Path.rs).

How the candidates were found: every function and data symbol of the debug objects, grouped by address so that constructor aliases count as one entity, with relocation edges between them. Roots: references from libbun_rust.a, JavaScriptCore, WTF, bmalloc and ICU (including weak references and the three hooks WebKit defines weakly and Bun overrides), the symbols.* export lists, and the static initializers. Debug info, .eh_frame and ASAN metadata were excluded, because ASAN makes every function reference itself. Each unreachable entity was then re-checked with rg on the current tree. Header-only items came from a separate read of the headers.

Verification: bun bd. The new tests in arraybuffersink.test.ts (constructor name, length, new and plain call both produce a working sink, prototype linkage) and FormData.test.ts (entries(), keys(), values(), the default iterator, iterator result shape, forEach() argument order, thisArg, and the TypeError for a non callable callback) pass on this branch and on the released bun, as expected for a deletion: they guard the code that stays. They deliberately do not assert instanceof against Bun.ArrayBufferSink, because the generated constructor has no prototype property today (a pre-existing bug, reported separately). bun bd test on test/js/web/fetch/headers.test.ts, headers-case.test.ts, abort/abort.test.ts, html/FormData.test.ts, encoding/text-encoder.test.js, urlpattern/urlpattern.test.ts, url/url.test.ts, web-globals.test.js, websocket/error-event.test.ts, fetch/wasm-streaming.test.ts, timers/performance.test.js, timers/performance-entries.test.ts, workers/message-port-pipe.test.ts, streams/streams.test.js, test/js/bun/cookie/cookie-map.test.ts, util/arraybuffersink.test.ts, util/filesink.test.ts, md/md-react.test.ts, test/js/node/perf_hooks/perf_hooks.test.ts, http/node-http-server-socket-end-drain.test.ts, test/js/deno/event/event.test.ts and custom-event.test.ts. cargo check --workspace, plus bun_jsc and bun_paths on the windows and darwin targets. clang-format and prettier are clean. After the deletions, rg over src, packages, src/codegen and the codegen output finds no reference to any removed name.

Files that #39618 also edits, in different places: src/codegen/generate-jssink.ts, node/JSNodeHTTPServerSocket.cpp, JSAbortController.cpp, JSCloseEvent.cpp, JSCustomEvent.cpp, JSPerformanceObserver.cpp, JSPerformanceServerTiming.cpp, JSPerformanceTiming.cpp, JSWebSocket.cpp. #39618 also deletes JSErrorHandler.cpp, in which this PR changes one constructor argument; whichever lands second keeps the deletion. DOMPromise::whenPromiseIsSettled() (the whole of JSDOMPromise.cpp) is unreachable too, but #39618 removes the rest of that class, so the header and the .cpp are best deleted together once it has landed; it is left out here on purpose.

Found unreachable but left alone on purpose:

  • Everything the six open dead-code PRs already delete (about 860 lines of this analysis overlapped with them, mostly bindings.cpp, headers.h, CryptoUtil.cpp, llhttp, JSErrorHandler and ncrypto) was dropped from this PR.
  • The resource timing implementation classes (PerformanceResourceTiming, PerformanceServerTiming, ResourceTiming, NetworkLoadMetrics) are never constructed, but their JS constructors and prototypes are web visible, so a clean removal has to reshape the wrappers, and ResourceTiming.h is touched by Remove dead code from C++ bindings, bindgen glue, ast, and orphaned scripts #39581.
  • JSCrossRealmTransformState and crossRealmTransformStateStructure are never instantiated, but the streams headers document them as deliberately kept scaffolding and their subspace slots live in files touched by Remove dead code from bun-uws, the native BufferList class, and built-in JS #37659.
  • The 40 <Class>_getter functions that WEBCORE_GENERATED_CONSTRUCTOR_GETTER expands in ZigGlobalObject.cpp, the eight sink constructor accessors and performanceObject() in ZigGlobalObject.h: dead, but both files are rewritten by open PRs.
  • ScriptExecutionContext::getMainThreadScriptExecutionContext() is used on Windows, JSPerformanceEntry::subspaceForImpl() is used through subspaceFor<> behind an assert (release builds reference it), and the int8 convertToInteger* instantiations are reached through bindgen's IDLByte. All live.
  • us_socket_t::write_fd (windows stub in src/uws_sys/us_socket_t.rs), the ReadWithoutLaunch mode of the windows shim, and the uws_app_run / uws_app_listen C++ definitions become removable once Remove dead code from uws_sys, webcore bindings, crash_handler, and scripts #37181 and Remove dead code from the JSC FFI glue, WebCore bindings, usockets, built-in JS, and orphaned scripts #39618 land.
  • The remaining hawk findings are fields of FFI mirror structs and enum variants that mirror external code tables, which the repo keeps on purpose (see the overrides in hawk.toml). Removing every #[allow(dead_code)] under src and checking the linux, darwin and windows targets found no item that is dead on all three.

…wo Rust helpers

Link-level reachability over the debug objects found functions that nothing
reaches: the toWrapped() statics of 17 wrapper classes, the reference taking
toJS() overloads of 11 types, unused DeferredPromise and DOMPromise entry
points, unused Event and ErrorEvent constructors, and a number of single leaf
functions. Header-only items (per-name accessors in HTTPHeaderIdentifiers and
MarkdownTagStrings, the Set variant of JSDOMIterator, FetchHeaders guard
helpers, two common strings) and the unused construct() method that
generate-jssink.ts emitted for every sink are removed as well.
@coderabbitai

coderabbitai Bot commented Aug 21, 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: 1fb4fd6c-9cd5-48ca-a004-eac5a95439f4

📥 Commits

Reviewing files that changed from the base of the PR and between 2f1dd37 and 1d35ff5.

📒 Files selected for processing (73)
  • src/codegen/generate-jssink.ts
  • src/jsc/PluginRunner.rs
  • src/jsc/bindings/BunCommonStrings.h
  • src/jsc/bindings/BunMarkdownTagStrings.h
  • src/jsc/bindings/ErrorCode.cpp
  • src/jsc/bindings/ErrorCode.h
  • src/jsc/bindings/JSBakeResponse.cpp
  • src/jsc/bindings/JSBakeResponse.h
  • src/jsc/bindings/node/JSNodeHTTPServerSocket.cpp
  • src/jsc/bindings/node/JSNodeHTTPServerSocket.h
  • src/jsc/bindings/webcore/CustomEvent.cpp
  • src/jsc/bindings/webcore/CustomEvent.h
  • src/jsc/bindings/webcore/ErrorEvent.cpp
  • src/jsc/bindings/webcore/ErrorEvent.h
  • src/jsc/bindings/webcore/Event.cpp
  • src/jsc/bindings/webcore/Event.h
  • src/jsc/bindings/webcore/FetchHeaders.h
  • src/jsc/bindings/webcore/HTTPHeaderIdentifiers.h
  • src/jsc/bindings/webcore/HTTPHeaderMap.cpp
  • src/jsc/bindings/webcore/HTTPHeaderMap.h
  • src/jsc/bindings/webcore/JSAbortController.cpp
  • src/jsc/bindings/webcore/JSAbortController.h
  • src/jsc/bindings/webcore/JSCloseEvent.cpp
  • src/jsc/bindings/webcore/JSCloseEvent.h
  • src/jsc/bindings/webcore/JSCookieMap.cpp
  • src/jsc/bindings/webcore/JSCookieMap.h
  • src/jsc/bindings/webcore/JSCustomEvent.cpp
  • src/jsc/bindings/webcore/JSCustomEvent.h
  • src/jsc/bindings/webcore/JSDOMFormData.cpp
  • src/jsc/bindings/webcore/JSDOMFormData.h
  • src/jsc/bindings/webcore/JSDOMIterator.h
  • src/jsc/bindings/webcore/JSDOMPromiseDeferred.cpp
  • src/jsc/bindings/webcore/JSDOMPromiseDeferred.h
  • src/jsc/bindings/webcore/JSDOMURL.cpp
  • src/jsc/bindings/webcore/JSDOMURL.h
  • src/jsc/bindings/webcore/JSErrorEvent.cpp
  • src/jsc/bindings/webcore/JSErrorEvent.h
  • src/jsc/bindings/webcore/JSErrorHandler.cpp
  • src/jsc/bindings/webcore/JSEventEmitter.h
  • src/jsc/bindings/webcore/JSEventEmitterCustom.cpp
  • src/jsc/bindings/webcore/JSEventListener.cpp
  • src/jsc/bindings/webcore/JSEventListener.h
  • src/jsc/bindings/webcore/JSFetchHeaders.cpp
  • src/jsc/bindings/webcore/JSFetchHeaders.h
  • src/jsc/bindings/webcore/JSMessageChannel.cpp
  • src/jsc/bindings/webcore/JSMessageChannel.h
  • src/jsc/bindings/webcore/JSPerformanceEntry.cpp
  • src/jsc/bindings/webcore/JSPerformanceEntry.h
  • src/jsc/bindings/webcore/JSPerformanceObserver.cpp
  • src/jsc/bindings/webcore/JSPerformanceObserver.h
  • src/jsc/bindings/webcore/JSPerformanceObserverEntryList.cpp
  • src/jsc/bindings/webcore/JSPerformanceObserverEntryList.h
  • src/jsc/bindings/webcore/JSPerformanceServerTiming.cpp
  • src/jsc/bindings/webcore/JSPerformanceServerTiming.h
  • src/jsc/bindings/webcore/JSPerformanceTiming.cpp
  • src/jsc/bindings/webcore/JSPerformanceTiming.h
  • src/jsc/bindings/webcore/JSTextEncoder.cpp
  • src/jsc/bindings/webcore/JSTextEncoder.h
  • src/jsc/bindings/webcore/JSURLPattern.cpp
  • src/jsc/bindings/webcore/JSURLPattern.h
  • src/jsc/bindings/webcore/JSURLSearchParams.cpp
  • src/jsc/bindings/webcore/JSURLSearchParams.h
  • src/jsc/bindings/webcore/JSWasmStreamingCompiler.cpp
  • src/jsc/bindings/webcore/JSWasmStreamingCompiler.h
  • src/jsc/bindings/webcore/JSWebSocket.cpp
  • src/jsc/bindings/webcore/JSWebSocket.h
  • src/jsc/bindings/webcore/URLPattern.cpp
  • src/jsc/bindings/webcore/URLPattern.h
  • src/jsc/bindings/webcore/streams/JSReadableStreamAsyncIterator.cpp
  • src/jsc/bindings/webcore/streams/JSReadableStreamAsyncIterator.h
  • src/paths/Path.rs
  • test/js/bun/util/arraybuffersink.test.ts
  • test/js/web/html/FormData.test.ts
💤 Files with no reviewable changes (67)
  • src/jsc/bindings/ErrorCode.h
  • src/jsc/bindings/JSBakeResponse.cpp
  • src/jsc/bindings/BunMarkdownTagStrings.h
  • src/jsc/bindings/webcore/JSPerformanceServerTiming.h
  • src/jsc/bindings/webcore/JSURLPattern.cpp
  • src/jsc/bindings/ErrorCode.cpp
  • src/jsc/bindings/webcore/JSTextEncoder.h
  • src/jsc/bindings/webcore/FetchHeaders.h
  • src/jsc/bindings/webcore/JSCloseEvent.h
  • src/jsc/bindings/webcore/JSWebSocket.h
  • src/jsc/bindings/webcore/JSWasmStreamingCompiler.cpp
  • src/jsc/bindings/webcore/JSEventEmitter.h
  • src/jsc/bindings/webcore/JSAbortController.cpp
  • src/jsc/bindings/webcore/JSTextEncoder.cpp
  • src/jsc/bindings/webcore/JSCloseEvent.cpp
  • src/jsc/bindings/webcore/HTTPHeaderMap.cpp
  • src/jsc/bindings/webcore/URLPattern.cpp
  • src/jsc/bindings/webcore/JSEventEmitterCustom.cpp
  • src/jsc/bindings/webcore/JSPerformanceServerTiming.cpp
  • src/jsc/bindings/webcore/JSCustomEvent.cpp
  • src/jsc/bindings/webcore/JSWebSocket.cpp
  • src/paths/Path.rs
  • src/jsc/bindings/webcore/JSCustomEvent.h
  • src/jsc/bindings/webcore/JSPerformanceObserver.h
  • src/codegen/generate-jssink.ts
  • src/jsc/bindings/webcore/JSErrorEvent.h
  • src/jsc/bindings/webcore/JSURLSearchParams.h
  • src/jsc/bindings/webcore/JSErrorEvent.cpp
  • src/jsc/bindings/webcore/HTTPHeaderMap.h
  • src/jsc/bindings/webcore/JSDOMURL.cpp
  • src/jsc/bindings/webcore/URLPattern.h
  • src/jsc/bindings/webcore/Event.h
  • src/jsc/bindings/webcore/JSCookieMap.h
  • src/jsc/bindings/webcore/JSAbortController.h
  • src/jsc/bindings/webcore/JSDOMFormData.h
  • src/jsc/bindings/webcore/JSDOMFormData.cpp
  • src/jsc/bindings/webcore/JSPerformanceTiming.h
  • src/jsc/bindings/webcore/JSPerformanceTiming.cpp
  • src/jsc/bindings/webcore/JSMessageChannel.cpp
  • src/jsc/bindings/webcore/JSPerformanceObserverEntryList.h
  • src/jsc/bindings/webcore/JSPerformanceEntry.cpp
  • src/jsc/bindings/webcore/JSFetchHeaders.cpp
  • src/jsc/bindings/webcore/JSDOMPromiseDeferred.h
  • src/jsc/bindings/BunCommonStrings.h
  • src/jsc/bindings/node/JSNodeHTTPServerSocket.cpp
  • src/jsc/bindings/webcore/CustomEvent.cpp
  • src/jsc/bindings/webcore/JSPerformanceObserverEntryList.cpp
  • src/jsc/bindings/node/JSNodeHTTPServerSocket.h
  • src/jsc/bindings/webcore/JSCookieMap.cpp
  • src/jsc/PluginRunner.rs
  • src/jsc/bindings/webcore/CustomEvent.h
  • src/jsc/bindings/webcore/streams/JSReadableStreamAsyncIterator.cpp
  • src/jsc/bindings/webcore/JSPerformanceObserver.cpp
  • src/jsc/bindings/webcore/JSPerformanceEntry.h
  • src/jsc/bindings/webcore/JSFetchHeaders.h
  • src/jsc/bindings/webcore/JSDOMURL.h
  • src/jsc/bindings/webcore/Event.cpp
  • src/jsc/bindings/webcore/JSURLSearchParams.cpp
  • src/jsc/bindings/webcore/HTTPHeaderIdentifiers.h
  • src/jsc/bindings/webcore/ErrorEvent.h
  • src/jsc/bindings/webcore/JSDOMPromiseDeferred.cpp
  • src/jsc/bindings/webcore/streams/JSReadableStreamAsyncIterator.h
  • src/jsc/bindings/webcore/JSMessageChannel.h
  • src/jsc/bindings/webcore/ErrorEvent.cpp
  • src/jsc/bindings/JSBakeResponse.h
  • src/jsc/bindings/webcore/JSWasmStreamingCompiler.h
  • src/jsc/bindings/webcore/JSURLPattern.h

Included review availability: 4 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.


Walkthrough

Changes

The PR removes obsolete generated and WebCore binding APIs. It narrows wrapper conversions to newly created objects, simplifies iterator and promise APIs, removes event-listener metadata, and adds constructor and FormData iteration tests.

Binding API cleanup

Layer / File(s) Summary
Generated and JSC API cleanup
src/codegen/generate-jssink.ts, src/jsc/PluginRunner.rs, src/jsc/bindings/..., test/js/bun/util/arraybuffersink.test.ts
Removed generated sink construct methods, forwarding helpers, obsolete binding accessors, and the global-object socket creation overload. Added ArrayBufferSink constructor coverage.
WebCore construction and header APIs
src/jsc/bindings/webcore/CustomEvent.*, ErrorEvent.*, Event.*, FetchHeaders.h, HTTPHeaderIdentifiers.h, HTTPHeaderMap.*, URLPattern.*
Removed legacy event constructors and factories, mutable header APIs, generated header accessors, string-based header removal, and URLPattern::Compatible construction.
Wrapper conversion ownership APIs
src/jsc/bindings/webcore/JS*.{h,cpp}
Removed existing-object toJS and toWrapped helpers. Newly created wrapper conversions remain, with owning Ref and RefPtr inputs where required.
Promise, iterator, and listener API narrowing
src/jsc/bindings/webcore/JSDOMIterator.h, JSDOMPromiseDeferred.*, JSEventListener.*, JSReadableStreamAsyncIterator.*, test/js/web/html/FormData.test.ts
Removed iterator type traits, set-specific paths, synchronous promise rejection overloads, event-listener markup state, and iterator prototype helpers. Added FormData iteration and forEach() tests.
Path separator API cleanup
src/paths/Path.rs
Removed PathSeparators::POSIX; numeric decoding still returns Posix.

Suggested reviewers: jarred-sumner

Merge Risk: ⚪ Minimal · up to 1d35f

This PR removes unreachable binding, code-generation, and Rust helpers while preserving the tested behavior; no actionable merge-blocking risk remains beyond normal focused test checks.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: removing dead code from WebCore bindings, JSSink code generation, and Rust helpers. It is concise and specific.
Description check ✅ Passed The description explains the problem, lists the removed code, documents intentional exclusions, and provides detailed build, test, platform, formatting, and reference-search verification. It does not …
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.
Full details: Description check

Explanation

The description explains the problem, lists the removed code, documents intentional exclusions, and provides detailed build, test, platform, formatting, and reference-search verification. It does not use the exact template headings, but it includes all required information.


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

These pin the surfaces that the edited sink codegen and JSDOMIterator.h
serve: the generated constructor's name, length, call and construct
behaviour, and the Map style entries(), keys(), values() and forEach()
of FormData.
Comment thread src/jsc/bindings/webcore/JSDOMIterator.h Outdated
@robobun

robobun commented Aug 21, 2026 •

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

✅ @alii, your commit 1d35ff50a08767b6319e33da3537b86b75084e1d passed in Build #105441! 🎉


🧪   To try this PR locally:

bunx bun-pr 39929

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

bun-39929 --bun

Comment thread src/jsc/bindings/webcore/JSEventListener.h
…ner accessors

With wasCreatedFromMarkup() gone, m_wasCreatedFromMarkup was only ever
written. Drop the field, the CreatedFromMarkup enum, the constructor
parameter, and the two call sites that passed CreatedFromMarkup::No.
Comment thread src/jsc/bindings/webcore/JSDOMIterator.h Outdated
Comment thread src/jsc/bindings/webcore/ErrorEvent.h
#39618 removes the rest of the DOMPromise class. Deleting this last
member here would leave the two pull requests fighting over
JSDOMPromise.h, and the header and JSDOMPromise.cpp can be deleted
together once both have landed.
…ns left behind

With the Set iterator gone, JSDOMIteratorType has one value and
EnableIfMap is always true. Drop both, the type member of the four
traits structs, and the <type_traits> include. The removed ErrorEvent
constructors were the only users of Strong.h, StrongInlines.h and
EventNames.h in ErrorEvent.h and ErrorEvent.cpp.

@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 re-reviewed after 82d96bf / 59b6a89 / c31c835 — the three follow-ups I asked for (the m_wasCreatedFromMarkup chain, the JSDOMIteratorType/EnableIfMap scaffolding, and the orphaned ErrorEvent includes) are all done, and this pass found no new issues. Given the scope (73 files across the WebCore/JSC bindings, plus the JSDOMIterator template rework and the jssink codegen edit), a human sign-off is still worthwhile. One doc nit: the description still lists DOMPromise::whenPromiseIsSettled() / JSDOMPromise.cpp as deleted, but 59b6a89 kept it.

What was reviewed:

  • Spot-checked that removed toWrapped/toJS(T&) overloads have no remaining callers and that IDLInterface<T> conversions for these types aren't instantiated.
  • Verified the JSDOMIterator.h de-templating keeps asJS/appendForEachArguments semantics for the four Map-style traits; new FormData iteration tests cover it.
  • Confirmed PathSeparators::POSIX removal leaves from_u8(2) → Posix and all enum-variant match arms intact.
  • Confirmed HTTPHeaderIdentifiers::Index is still referenced (Index::Count, Index::Authority static_asserts) after the accessor macro removal.
Extended reasoning...

Overview

Dead-code removal across 73 files: 17 toWrapped() statics, 11 toJS(..., T&) overloads, unused Event/ErrorEvent/CustomEvent constructors, four DeferredPromise::reject overloads plus promise(), header-only accessor macros (HTTPHeaderIdentifiers, MarkdownTagStrings), the Set half of JSDOMIterator's SFINAE dispatch (then, per my earlier comment, the whole dispatch), the per-sink ::construct in generate-jssink.ts, two BunCommonStrings entries, FetchHeaders guard accessors + EnumTraits, JSEventListener::functionName/wasCreatedFromMarkup and its plumbing, and two Rust items (PluginRunner::could_be_plugin re-export, PathSeparators::POSIX). Two new test blocks pin the surfaces that were edited rather than only pruned.

Security risks

None. Pure deletions of unreferenced symbols; no new inputs, no changed validation, no auth/crypto surface.

Level of scrutiny

Medium-high. Each individual deletion is mechanical and self-verifying (declaration removed with definition → any missed caller fails to compile, not link), and the methodology (link-level reachability rooted at Rust/WebKit/export lists, then rg re-check) is sound. But the aggregate touches ~70 core-binding files, includes a small template refactor in JSDOMIterator.h used by four iterator types, and edits a codegen script. That's beyond what I'd auto-approve.

Other factors

  • All three of my prior inline findings were addressed in 82d96bf and c31c835; threads are resolved.
  • 59b6a89 reverted the whenPromiseIsSettled deletion but the PR description still lists it as removed — worth syncing before merge.
  • The PR notes overlap with six open dead-code PRs (esp. #39618, which also deletes JSErrorHandler.cpp); whichever lands second needs a rebase, so a maintainer should sequence these.
  • CI build #102577 was still building at last timeline update; result not yet visible here.
  • The two candidate issues raised and refuted this run (stale could_be_plugin mention in the PluginRunner.rs module doc) are cosmetic — the doc line still accurately describes where the helper lives.

@robobun

robobun commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

The description is already in sync with 59b6a89: the symbol list no longer includes DOMPromise::whenPromiseIsSettled(), and the Notes say that it and JSDOMPromise.cpp are left out on purpose until #39618 (which removes the rest of DOMPromise) has landed, so that the header and the .cpp can be deleted together.

@robobun

robobun commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

Status: ready for review at c31c835.

CI (build 102577) builds on every platform and passes on 177 of 179 jobs. The two red jobs are not related to this change and are reported separately: test/js/bun/http/bun-server.test.ts on Windows 2019 x64 (a heap-stats assertion that also fails on main, red on both builds of this PR) and test/js/bun/util/filesystem_router.test.ts on Alpine aarch64 (a SIGSEGV inside the SVE2 memrmem kernel in highway_strings.cpp, reached from the resolver on the bundler thread; this PR does not touch that code). The remaining entries in the build are retries that passed.

Because this PR only deletes unreachable code, the new tests pass before and after the change by design; they pin the two surfaces whose code was edited (the sink constructor and FormData iteration). The evidence that the removed functions are unreachable is in the description.

Sequencing: #39618 edits ten of these files in other places and deletes JSErrorHandler.cpp, so whichever of the two lands second needs a small rebase.

@alii

alii commented Aug 25, 2026

Copy link
Copy Markdown
Member

Binary size impact?

@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.

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>
@alii

alii commented Aug 25, 2026

Copy link
Copy Markdown
Member

@robobun binary size impact?

@robobun

robobun commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Measuring now: release builds of the merge base (2f1dd37) and of the PR head (1d35ff5) on linux x64, comparing the stripped binary and the section sizes. Numbers to follow in this thread.

@robobun

robobun commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Binary size impact: none on the shipped binary. Release builds (linux x64, bun scripts/build.ts --profile=release) of the merge base 2f1dd377dd and of the PR head 1d35ff50a0, same machine, same caches:

base PR delta
bun (stripped) file size 74,307,072 74,307,072 0
.text 52,089,356 52,089,356 0
.rodata 21,400,680 21,400,680 0
.data + .bss and every other loaded section identical identical 0
PT_LOAD segment sizes identical identical 0
function symbols in bun-profile 90,345 90,345 0
bun-profile (unstripped) file size 273,800,112 273,768,304 -31,808

The only shrinkage is DWARF (.debug_info -8,286, .debug_str -7,176, .debug_loclists -4,726, .debug_line -3,893, and so on), which the stripped release binary does not carry.

Why zero: the release link already dead-strips unreferenced functions (-ffunction-sections/-fdata-sections with --gc-sections, plus LTO). None of the removed functions was present in the base release binary (llvm-nm on bun-profile finds no JSFetchHeaders::toWrapped, DeferredPromise::promise(), HTTPHeaderMap::remove(StringView) and so on at the base either). So this PR is a source and compile-time cleanup, not a size win; the expected effects are fewer lines to read and maintain and slightly less to compile and to carry in debug builds.

Jarred-Sumner added a commit that referenced this pull request Aug 27, 2026
…her crates (#40610)

### Problem
- The workspace denies `dead_code` and `unreachable_pub`, and earlier
sweeps removed the `pub` items a cross-crate analysis can see. What is
left is code no lint reports: branches behind constant conditions, `pub`
enum variants that nothing constructs, `pub` struct fields that nothing
reads, and commented-out code.
- The largest case is the js lexer: `LexerType` carried seven const
generic parameters for a JSON mode (`IS_JSON`, `ALLOW_COMMENTS`, ...)
that no caller ever set. The only instantiation is the default one, so
every `if IS_JSON` body in `src/js_parser/lexer.rs` was unreachable.
JSON is parsed by `src/parsers/json.rs`.

### Fix
- Delete the items. 83 source files, +221 / -1653. Every candidate was
checked with `rg` over `src/`, `build/debug/codegen/` and
`src/codegen/`, including `#[cfg(windows)]` and macOS paths. The Notes
list each one.
- The lexer becomes a plain `struct Lexer<'a>`: the `JsonOptionsT`
trait, the `NewLexer` alias, the `lexer_impl_header!` macro and the
`generic_const_exprs` feature gate go with the JSON branches. The only
JS-visible change is none: the default instantiation was the only one.
- `bun_runtime::Error` loses 85 unit variants that are never built (the
X509 codes live in `bun_http::CertError`; `InstallFailed` and friends
are only ever nested as `Error::Install(..)`). The `AllocatorVTable`
keeps only `free`, the one slot `StdAllocator` dispatches.
- New source lint
`test/internal/source-lints/literal-bool-condition.test.ts`: a
statement-level `if true {` / `if false {` outside `#[cfg(test)]` code
fails the lint. rustc and clippy accept both, so the dead `if false {
break 'outer; }` in `doStep5.rs` and the always-taken `if true {` block
in `Watcher.rs` (unwrapped here) had no other guard. The lint fails on
`main` with those two lines and passes with this PR.
- Verified: `bun bd`, `bun run rust:check-all` (12 targets), `cargo
clippy --workspace`, `cargo check --workspace --tests`, `cargo fmt
--check`. `bun bd test` on transpiler, bundler edge cases, shell, yaml,
zstd, transpiler cache, `Bun.write`, `Bun.file`, sourcemap, resolver
cache, WebSocket client, `bun add`/`bun remove`, lockfile sync, archive,
`bun:test`, `--watch`, and the source lints (about 2,700 tests, 0
failures attributable to this change; see Notes).

### Background
- `dead_code` does not report a `pub` item, a trait impl, an enum
variant that a `match` arm names, or a field that a compound assignment
(`+=`) touches. Each of those counts as a use to rustc even when nothing
reads the result.
- A `const bool` that is the same in every build (`const ALLOW_TMPFILE:
bool = false`, a trait const no impl overrides, a const generic no
caller sets) makes one side of its `if` unreachable, but rustc still
type-checks and keeps that side. The removed branches are all of this
kind. Flags that vary per build (`IS_WINDOWS`, `IS_DEBUG`,
`ENABLE_ASAN`) and the debug toggles (`TRACING`, `VERBOSE_FS`-style
logging switches that still have a body) were left alone.
- `BunBuiltinNames.h` entries and JS private names can be referenced by
string (`$getByIdDirectPrivate(this, "writer")`), so a name with no
`$name` hit is not dead. Two such candidates were checked and kept.

<details><summary>Notes</summary>

Removed, constant conditions:

- `src/js_parser/lexer.rs`: the 7 const generic parameters of
`LexerType`, the `JsonOptionsT` trait, `DefaultJsonOptions`, the
`NewLexer` alias and the `lexer_impl_header!` macro. 30 `if IS_JSON`
bodies, `assert_not_json` and its 13 calls, the `is_ascii_only` field
(only written in JSON mode), `Error::JSONStringsMustUseDoubleQuotes`,
and the `if !FeatureFlags::ALLOW_JSON_SINGLE_QUOTES` block.
`src/js_parser/lib.rs` drops `#![feature(adt_const_params,
generic_const_exprs)]`, which nothing else in the crate used.
- `src/bun_core/feature_flags.rs`: `ENABLE_ENTRY_CACHE` (always true:
the "cache disabled" tails of `read_directory_error` and
`read_directory_with_iterator` in `src/resolver/lib.rs`), `VERBOSE_FS`
(always false: two `prettyln!` blocks in `src/resolver/fs.rs` and the
`bstr::BStr` import), `HARDCODE_LOCALHOST_TO_127_0_0_1` (always false:
the rewrite in `HTTPContext::connect` and `WebSocketUpgradeClient`),
`ALLOW_JSON_SINGLE_QUOTES` (only read by the lexer JSON mode).
- `src/sys/tmp.rs`: `ALLOW_TMPFILE = false` with the `O_TMPFILE` open
and `linkat` paths and the `using_tmpfile` field.
`RuntimeTranspilerCache.rs` always unlinks the tmp name on failure now,
which is what the `!using_tmpfile` guard already did. The non-Linux
`O::TMPFILE` consts and `linkat_tmpfile` stubs in `src/sys/lib.rs` had
no other caller (`src/install/npm.rs` uses them under `cfg(linux)`).
- `src/libarchive/lib.rs`: `ArchiveAppender::HAS_APPEND_MUTABLE`, no
impl overrides the `false` default. With it: `append_mutable`, the `if
A::HAS_APPEND_MUTABLE` block, `Context::all_files`, `EntryMap`,
`U64Context` and its two impls, and the `all_files` initializer in
`create_command.rs`.
- `src/bundler/linker_context/doStep5.rs`: `if false { break 'outer; }`
and the label. `src/watcher/Watcher.rs`: an `if true {` block around the
"Added to watch list" log, unwrapped.
- `src/io/PipeWriter.rs`: `PosixStreamingWriterParent::HAS_ON_READY`,
set by both impls (the macro and `Terminal.rs`), read by nothing.

Removed, enum variants nothing constructs (each with its `name()` arm
and match arms):

- `bun_runtime::Error` (`src/runtime/error.rs`): `Panic`,
`RequestBodyNotReusable`, `DNSResolveFailed`, `TooManyRedirects`,
`ConnectionRefused`, `RedirectURLInvalid`, the 66 X509 verification
codes from `UNABLE_TO_GET_ISSUER_CERT` to
`UNKNOWN_CERTIFICATE_VERIFICATION_ERROR`, `InstallFailed`,
`InvalidPackageJSON`, `PathAlreadyExists`, `InvalidTarget`,
`OpenFailed`, `UnableToDecode`, `SocketClosed`, `StackOverflow`, `Test`,
`MissingTranspileExtra`, `PluginError`, `Name`, `EscapeCalledTwice`. The
or-patterns in `install_command.rs`, `pm_update_package_json.rs` and
`jsc_hooks.rs` keep their live alternatives.
- `bun_core::strings::BOM::{Utf16Be, Utf32Le, Utf32Be}`: `detect()` only
returns `Utf8` and `Utf16Le`. With them: the three byte-pattern consts,
the `_ =>` arms in the two `remove_and_convert_*` functions, and the
commented-out detection lines.
- `bun_shell_parser`: `Token::{Dollar, Eq}` and `TokenTag::{Dollar, Eq}`
(the lexer never pushes them), with the `TestToken` mirrors and JSON
arms in `src/runtime/shell/shell_body.rs`.
- `ShellErr::Todo` (`shell_body.rs`, `Builtin.rs`),
`bun_crash_handler::Error::InvalidDebugInfo` (patterns in
`crash_handler/lib.rs` and `jsc/btjs.rs`) and the
`bun_jsc::Error::InvalidDebugInfo` mirror,
`FetchFlags::PrintSourceAndClone` (`ModuleLoader.rs`, arm in
`jsc_hooks.rs`), yaml `ParseError::InvalidIndentation` and the
`ParseResultError::InvalidIndentation` it alone produced,
`bun_sourcemap::Error::Unknown`.

Removed, fields nothing reads:

- `AllocatorVTable::{alloc, resize, remap}` (`src/bun_alloc/lib.rs`):
only `free` is ever dispatched. With them:
`NO_ALLOC`/`NO_RESIZE`/`NO_REMAP`, `MimallocAllocator` and its four
functions in `basic.rs`, `default_alloc::{malloc_aligned,
realloc_aligned}` and `Alignment::to_byte_units`.
- `ArgumentsSlice::all` (`src/jsc/CallFrame.rs`),
`ParseTask::tree_shaking` (`src/bundler/ParseTask.rs`, 11 writers in
`bundle_v2.rs`; the parser reads `topts.tree_shaking`),
`JSMeta::entry_point_part_index` (`LinkerGraph.rs`, written in
`scanImportsAndExports.rs`), `NetworkSink::high_water_mark`
(`streams.rs`, `s3/client.rs`, with the `part_size` locals that fed it),
`CopyFile::read_off`, the POSIX `ReadFile::byte_store`,
`file_sink::Options::close`, `ZstdReaderArrayList::total_out`,
`Cloner::trees_count`.

Removed, commented-out code older than six months (blame on the line, or
on the Zig line the port copied):

- C++: `ImportMetaObject.cpp`, `InspectorHTTPServerAgent.cpp`,
`JSDOMExceptionHandling.cpp`, `ncrypto.cpp`, `KeyObject.cpp`,
`EventTarget.cpp`, `JSPerformanceEntryCustom.cpp`, `MessageEvent.h`
(plus a duplicate `#include "MessagePort.h"`), `Performance.cpp`,
`Performance.h`, `PerformanceEntry.cpp`, `PerformanceObserver.cpp`,
`PerformanceResourceTiming.cpp`, `WebSocket.cpp`.
- Rust: `AstBuilder.rs`, `postProcessCSSChunk.rs`,
`postProcessJSChunk.rs`, `crash_handler/lib.rs`, `css/declaration.rs`,
`css/selectors/selector.rs`, `css/values/percentage.rs`,
`WebSocketUpgradeClient.rs`, `lexer.rs`, `parse_fn.rs`, `visit_expr.rs`,
`paths/resolve_path.rs`, `exec_command.rs`, `braces.rs`,
`sha_hmac/sha.rs`, `StaticHashMap.rs`, `ffi_body.rs`.
- `.classes.ts`: disabled entries in `sql.classes.ts`,
`sockets.classes.ts`, `server.classes.ts`, `jest.classes.ts`; a leftover
loop in `generate_uv_posix_stubs.ts`.

Declaration-only C++:
`CryptoKeyOKP::platformExportSpki/platformExportPkcs8`,
`JSX509Certificate::getPublicKey`, `KeyPairJobCtx::deinit`,
`BunShell`/`ShellError` in `BunObject.h`.

Checked and kept: `Terminal::get_slave_fd` (used by
`js_bun_spawn_bindings.rs`), `macro(writer)` and `macro(mockedFunction)`
in `BunBuiltinNames.h` (`$getByIdDirectPrivate(this, "writer")` in
`ConsoleObject.ts`, `BunCommonStrings.h`), css `Segment::Name` and
`CssModuleExport::is_referenced` (lightningcss data model), the
react_compiler variants and fields that mirror the upstream schema,
`Mode::ProductionDynamic` (bake scaffolding), the MySQL protocol fields
that mirror the wire format, the debug toggles `LOG_ALLOCATIONS`,
`DISABLE_COMPRESSION_IN_HTTP_CLIENT`, crash handler `ENABLE`,
`ENABLE_AUTO_CORK`/`ENABLE_ALLOCATOR_POOL`, and the wasm scaffolding
behind `IS_WASM`/`IS_BROWSER`.

Test runs: `test/js/web/fetch/fetch.test.ts` fails the same 26 tests
with the released `bun` in this container (root user, no network).
`Bun.write > copyFileRange is not available > on large files` hits its 5
s timeout under the ASAN debug build while filling a 256 MB buffer in
JS; the copy itself takes 0.6 s and the hash matches.

This PR repeats no deletion of the open dead-code PRs (#39929, #40122,
#40172, #40232, #40294, #40367, #40492, #40525, #40557), checked by
diffing the removed lines. Three files are shared with them in other
regions (`src/install/lockfile/Package.rs`,
`src/runtime/cli/create_command.rs`, `src/runtime/jsc_hooks.rs`).
</details>

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

---

**[review]** gate passed · iteration 2 · 84 files touched

<details><summary>fails on main (without fix)</summary>

```console
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/literal-bool-condition.test.ts
ninja: Entering directory `/workspace/bun/build/debug'
[1/166] gen generated_host_exports.rs
generated_host_exports.rs: 122 exports (host=5, lazy=10, generic=107, rust=0); 243 extern-C blocks audited
[2/166] gen ZigGeneratedClasses.{cpp,h,rs}
Found 2 classes from /workspace/bun/src/jsc/resolve_message.classes.ts
  - ResolveMessage (15 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 fro
... (truncated)

release without fix: 1 FAILED
bun test v1.4.1-canary.1 (9e0b058)

test/internal/source-lints/literal-bool-condition.test.ts:
(pass) scans a non-empty set of tracked Rust sources [0.09ms]
(pass) withoutTestItems keeps production code and blanks #[cfg(test)] items [0.09ms]
234 |     "fn after_strings() {}",
235 |   ]);
236 | });
237 | 
238 | test("if true { .. } / if false { .. } outside #[cfg(test)] code", () => {
239 |   expect(offenders).toEqual([]);
                          ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/bundler/linker_context/doStep5.rs:308: if false {",
+   "src/watcher/Watcher.rs:752: if true {",
+ ]

- Expected  - 1
+ Received  + 4

      at <anonymous> (/workspace/bun/test/internal/source-lints/literal-bool-condition.test.ts:239:21)
(fail) if true { .. } / if false { .. } outside #[cfg(test)] code [0.19ms]

 2 pass
 1 fail
 3 expect() calls
Ran 3 tests across 1 file. [798.00ms]
__F:1:S:0
```

</details>

<details><summary>passes on PR (with fix)</summary>

```console
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/literal-bool-condition.test.ts
bun test v1.4.1 (731aa92)

test/internal/source-lints/literal-bool-condition.test.ts:
(pass) scans a non-empty set of tracked Rust sources [2.29ms]
(pass) withoutTestItems keeps production code and blanks #[cfg(test)] items [4.24ms]
(pass) if true { .. } / if false { .. } outside #[cfg(test)] code [1.22ms]

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

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 631ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/126] gen generated_host_exports.rs
generated_host_exports.rs: 122 exports (host=5, lazy=10, generic=107, rust=0); 243 extern-C blocks audited
[2/126] gen ZigGeneratedClasses.{cpp,h,rs}
Found 2 classes from /workspace/bun/src/jsc/resolve_message.classes.ts
  - ResolveMessage (15 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
  - H2FrameParser (32 fields)
Found 
... (truncated)
```

</details>

<details><summary>diff hotspot</summary>

```
src/bun_alloc/basic.rs                             |  73 +--
 src/bun_alloc/lib.rs                               | 105 +---
 src/bun_core/feature_flags.rs                      |  14 -
 src/bun_core/string/immutable/unicode.rs           |  28 -
 src/bundler/AstBuilder.rs                          |   4 -
 src/bundler/LinkerGraph.rs                         |   3 -
 src/bundler/ParseTask.rs                           |   4 -
 src/bundler/bundle_v2.rs                           |   9 -
 src/bundler/linker_context/doStep5.rs              |   5 +-
 src/bundler/linker_context/postProcessCSSChunk.rs  |   9 -
 src/bundler/linker_context/postProcessJSChunk.rs   |   5 -
 .../linker_context/scanImportsAndExports.rs        |   2 -
 src/collections/StaticHashMap.rs                   |   7 -
 src/crash_handler/error.rs                         |   3 -
 src/crash_handler/lib.rs                           |   7 +-
 src/css/declaration.rs                             |   4 -
 src/css/selectors/selector.rs                      |  23 -
 src/css/values/percentage.rs                       |  11 -
 src/http/HTTPContext.rs                            |  16 +-
 .../websocket_client/WebSocketUpgradeClient.rs     |  19 +-
 src/install/lockfile.rs                            |   2 -
 src/install/lockfile/Package.rs                    |   4 +-
 src/io/PipeWriter.rs                               |   2 -
 src/js_parser/lexer.rs                             | 631 ++++-----------------
 src/js_parser/lib.rs                               |   6 -
 src/js_parser/parse/parse_fn.rs                    |   3 -
 src/js_parser/visit/visit_expr.rs                  |   6 -
 src/jsc/CallFrame.rs                               |   9 +-
 src/jsc/ModuleLoader.rs                            |   1 -
 src/jsc/RuntimeTranspilerCache.rs                  |   6 +-
 src/jsc/bindings/BunObject.h                       |   3 -
 src/jsc/bindings/ImportMetaObject.cpp              |   4 -
 src/jsc/bindings/InspectorHTTPSe
... (truncated)
```

</details>

**gate history** · 2 passed · 1 rejected · iteration 2

<details><summary>evidence per changed file</summary>

```
file                                                 reads  edits  tests
src/bun_alloc/basic.rs                                   0      0      0
src/bun_alloc/lib.rs                                     0      0      0
src/bun_core/feature_flags.rs                            1      0      0
src/bun_core/string/immutable/unicode.rs                 0      0      0
src/bundler/AstBuilder.rs                                0      0      0
src/bundler/LinkerGraph.rs                               0      0      0
src/bundler/ParseTask.rs                                 0      0      0
src/bundler/bundle_v2.rs                                 0      0      0
src/bundler/linker_context/doStep5.rs                    0      0      0
src/bundler/linker_context/postProcessCSSChunk.rs        0      0      0
src/bundler/linker_context/postProcessJSChunk.rs         0      0      0
src/bundler/linker_context/scanImportsAndExports.rs      0      0      0
src/collections/StaticHashMap.rs                         0      0      0
src/crash_handler/error.rs                               0      0      0
src/crash_handler/lib.rs                                 0      0      0
src/css/declaration.rs                                   0      0      0
(+ 68 more files)
```

</details>

<!-- robobun:evidence:end -->

---------

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
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 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.

2 participants