Skip to content

Remove dead code from the class and sink generators, JSBuffer, the bake client, bun-error, and the build scripts - #43378

Open
robobun wants to merge 1 commit into
mainfrom
robobun/048b8f82/dead-code-sweep
Open

robobun wants to merge 1 commit into
mainfrom
robobun/048b8f82/dead-code-sweep

Conversation

@robobun

@robobun robobun commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Problem

  • About 450 lines have no user. Example: 66 JSC_DECLARE_HOST_FUNCTION lines in JSBuffer.cpp declare functions at global scope, but the definitions are in namespace WebCore, so the declared functions do not exist. Example: the class generator emits a <Type>__ptrOffset constant for all 94 classes, and nothing reads it.
  • rustc, hawk, -Wunused-function and the --gc-sections link do not report them. They are prototypes without a definition, generator output, inline header members, type declarations, or write-only fields.

Fix

  • Delete each item: 32 files, 455 lines removed, no behavior change. The Notes list every symbol.
  • Correct because each name has zero references in src/, packages/, scripts/, test/ and build/debug/codegen/ outside its own definition. A clang AST pass over all 670 Bun translation units finds no reference to the removed C++ functions, template instantiations included.
  • The generated code only loses lines: ZigGeneratedClasses.{h,cpp} 1322, JSSink.{h,cpp} 99, zero added. WebCoreJSBuiltins.* is byte-identical.
  • Verified: bun bd, tsc (no new error), test/internal/source-lints (173 pass), and the suites in the Notes.

Background

  • JSC_DECLARE_HOST_FUNCTION(name) expands to a function prototype in the current namespace. A prototype that nothing defines or calls has no effect.
  • generate-classes.ts and generate-jssink.ts write the C++ wrapper classes for the native types in *.classes.ts. A symbol they emit is dead when no C++, Rust or generated file names it.
  • 31 other dead-code pull requests are open. This one deletes nothing that they delete. 19 files overlap at other lines.
Notes

Class and sink generators (src/codegen)

  • generate-classes.ts: extern "C" const size_t <Type>__ptrOffset and the offsetOfWrapped() member that only initialized it. rg ptrOffset hits only the generator.
  • generate-classes.ts: <Type>__createWithInitialValues and <Type>__createWithValuesAndInitialValues (emitted only for ShellInterpreter). No Rust or C++ file declares them. The create(vm, global, structure, ctx, values...) overload and its constructor had no other caller. ShellBindings.cpp uses the overload that also takes jsvalueArray, which stays. <Type>__createWithValues stays (Rust calls it).
  • generate-classes.ts: the onStructuredCloneTransfer Rust thunk. No C++ declares or calls __onStructuredCloneTransfer, and no type has on_structured_clone_transfer.
  • generate-classes.ts: rustModuleResolver.resolveFile (never called).
  • generate-jssink.ts: the JSSink_isSink declaration (no definition, no caller), createPrototype of the sink classes (prototypes come from createJSSinkPrototype, the controller createPrototype stays), the SinkID Sink constants of the constructor and controller classes (only JS<Name>Sink::Sink is read), the #if ENABLE(MEDIA_SOURCE) includes of BufferMediaSource.h and JSMediaSource.h (no such headers exist), and six commented-out lines from 2022 to 2024.
  • bundle-modules.ts: #define BUN_NATIVE_MODULE_START_INDEX (no reader, a comment in InternalModuleRegistry.cpp now names the real bound) and two .replace() calls for __debug_end__ / __assert_end__, which nothing emits.
  • bake-codegen.ts: bake_empty_file, written for a dependency edge of the removed CMake build.
  • cppbind.ts: the write-only fields isMany and isNonNull and the code that computed them. [[ZIG_NONNULL]] is still accepted.
  • bundle-functions.ts: const useThis = true and its unreachable arrow-function arm, and the "export type" comparison that the tokenizer regex can never produce. The emitted text is identical.

C++

  • JSBuffer.cpp: 66 JSC_DECLARE_HOST_FUNCTION(jsBuffer...) lines. They declare ::jsBufferPrototypeFunction_*. The definitions and the hash table are WebCore::jsBufferPrototypeFunction_*, defined before their first use.
  • WebSocket.cpp: static String hostName(const URL&, bool).
  • EventEmitter.h: hasEventListeners() and hasEventListeners(VM&, ASCIILiteral). EventTarget.h: hasEventListeners(). Every caller passes an Identifier or AtomString.
  • JSDOMExceptionHandling.h: the JSGlobalObject* overload of invokeFunctorPropagatingExceptionIfNecessary. All 13 callers pass a reference. A pointer argument does not convert to the remaining overload, so a missed caller fails to compile.
  • JSDOMWrapper.h: offsetOfWrapped(). Path.cpp, ZigSourceProvider.cpp: four unused using aliases.

Built-in TS

packages and scripts

  • packages/bun-error/bun-error.css: rules for #BunError-SourceLine-text-highlightExpression, .BunError-Indented, .BunError-divet, .BunError-error-muted. No file emits these names. index.tsx: the highlightColumnEnd prop (forwarded, never read) and let _i.
  • packages/bun-debug-adapter-protocol: FramerState, state, pendingLength, sizeBuffer, sizeBufferIndex in node-socket-framer.ts (the parser is position-based), and the extraTs parameter that no caller passes.
  • packages/bun-native-plugin-rs/headers/.../bundler_plugin.h: a stale committed copy (it lacks BUN_LOADER_HTML, YAML, XML). copy_headers.ts runs rm -rf headers and copies it again before bindgen, so nothing reads the committed file. headers/ is now in that package's .gitignore.
  • scripts/build: ConfigureResult.ninjaFile (never read), the zig color override in tty.ts (no stream has that name), the <cache>/cargo entry in clean.ts (nothing writes that directory).

Tests run with the debug build

test/internal/source-lints/ (173 pass), test/js/node/buffer-concat.test.ts, test/js/node/buffer-jit.test.ts (11 pass, the differential fuzzer test passes its 120 s limit under ASAN in this container and runs in 1.8 s with a release build), test/js/node/events/event-emitter.test.ts, test/js/bun/shell/bunshell-instance.test.ts, test/js/bun/shell/exec.test.ts, test/js/web/websocket/websocket-blob.test.ts, test/js/web/websocket/error-event.test.ts, test/js/web/url/url.test.ts, test/js/web/abort/abort.test.ts, test/js/web/broadcastchannel/broadcast-channel.test.ts, test/bake/dev/esm.test.ts, test/bake/dev/hot.test.ts, test/js/bun/util/arraybuffersink.test.ts, test/js/bun/util/filesink.test.ts, test/js/web/workers/structured-clone.test.ts, test/js/web/structured-clone-blob-file.test.ts, test/js/bun/runtime-error.test.ts, test/js/node/module/node-module-module.test.js.

No test is added. The change only deletes code that nothing references, so there is no behavior to assert. No Rust code changes (one comment), so rust:check-all has nothing to check.

How the candidates were found

  • A clang LibTooling pass over the 670 Bun translation units (per-file and unity). It records every declaration in Bun-owned files and every reference, with template instantiations visited and definitions linked to declarations by mangled name. It also records preprocessor-skipped ranges, so a name that appears in code that is not compiled on Linux is never a candidate.
  • Four search passes over scripts/, packages/, src/codegen and src/js.
  • A repo-wide identifier index and the diffs of the 31 open dead-code PRs, to drop anything they already delete.

Found, not deleted here

Clean, so the next run can skip it

  • Rust: the identifier index finds no function, type or constant that is named nowhere else. Every hit is a test, a #[no_mangle] export, a host_fn, or macro output.
  • C++: after the open PRs, the AST pass finds no other unreferenced free function, static function or non-inline method. The rest of its report is macro-generated accessors (HTTP_HEADERS_EACH_NAME, builtin names, *_getter), IDL converter specializations, and constructors.
  • src/js: no function with zero mentions, no module without a loader, every bun:internal-for-testing export has a test. No unused selector in src/runtime/bake/client/overlay.css (the log-* classes are built by concatenation).
  • src/symbols.txt matches the binary. No .zig file and no CMake reference is left outside comments. Commented-out code older than 6 months: 80 lines in total, most in bun-types doc examples.

…ke client, bun-error, and the build scripts

Each removed item has no reference in src/, packages/, scripts/, test/ or
the generated code outside its own definition. The generated C++ only
loses lines (ZigGeneratedClasses, JSSink). WebCoreJSBuiltins is
byte-identical.
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Warning

Review paused — included plan limit reached

Keep your review moving with free on-demand reviews.

  • Run this review for free

On-demand reviews are free for the next 2 days.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Promotion and pricing details

On-demand reviews are free for the next 2 days. After that, they cost $0.25 per reviewed file.

Review limit details

Or wait 34 seconds for your next included review.

Check out review usage here.

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: oven-sh/bun/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 587a7d52-b25b-4fa7-9feb-db181fcd1297

📥 Commits

Reviewing files that changed from the base of the PR and between 367d939 and dc1a38f.

📒 Files selected for processing (32)
  • packages/bun-debug-adapter-protocol/scripts/generate-protocol.ts
  • packages/bun-debug-adapter-protocol/src/debugger/node-socket-framer.ts
  • packages/bun-error/bun-error.css
  • packages/bun-error/index.tsx
  • packages/bun-native-plugin-rs/.gitignore
  • packages/bun-native-plugin-rs/headers/bun-native-bundler-plugin-api/bundler_plugin.h
  • scripts/build/clean.ts
  • scripts/build/configure.ts
  • scripts/build/tty.ts
  • src/codegen/bake-codegen.ts
  • src/codegen/bundle-functions.ts
  • src/codegen/bundle-modules.ts
  • src/codegen/cppbind.ts
  • src/codegen/generate-classes.ts
  • src/codegen/generate-jssink.ts
  • src/js/builtins.d.ts
  • src/js/builtins/CommonJS.ts
  • src/js/private.d.ts
  • src/jsc/bindings/InternalModuleRegistry.cpp
  • src/jsc/bindings/JSBuffer.cpp
  • src/jsc/bindings/JSDOMExceptionHandling.h
  • src/jsc/bindings/JSDOMWrapper.h
  • src/jsc/bindings/Path.cpp
  • src/jsc/bindings/ZigSourceProvider.cpp
  • src/jsc/bindings/webcore/EventEmitter.h
  • src/jsc/bindings/webcore/EventTarget.h
  • src/jsc/bindings/webcore/WebSocket.cpp
  • src/runtime/bake/bake.private.d.ts
  • src/runtime/bake/client/overlay.ts
  • src/runtime/bake/client/websocket.ts
  • src/runtime/bake/hmr-runtime-server.ts
  • src/runtime/generated_classes.rs

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

@robobun

robobun commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 3:32 PM PT - Sep 18th, 2026

❌ @robobun, your commit dc1a38f has 1 failures in Build #118011 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 43378

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

bun-43378 --bun

@robobun

robobun commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator Author

Status: ready for review

  • Scope: deletions only. 32 files, 455 lines removed, no behavior change.
  • How each item was checked: the name has zero references in src/, packages/, scripts/, test/ and build/debug/codegen/ outside its own definition. For the C++ items, a clang AST pass over all 670 Bun translation units also finds no reference, template instantiations included.
  • Build: bun bd passes. The generated C++ only loses lines (ZigGeneratedClasses, JSSink), and WebCoreJSBuiltins.* is byte-identical to main.
  • Tests: test/internal/source-lints (173 pass) and the suites listed in the Notes of the description, all with the debug build.
  • CI (build 118011): 180 of 181 jobs pass, including all 13 build lanes (macOS, Linux glibc, musl and ASAN, Android, FreeBSD, Windows). The one red job is test/bake/deinitialization.test.ts on Alpine aarch64. The same test fails on other open PRs at this time, and this diff does not change the code it runs.
  • Overlap: none of the 31 open dead-code PRs deletes the same lines. 19 files overlap at other lines.
  • Open: one review thread on the JSBuffer.cpp forward declarations waits for a maintainer answer (keep the deletion, move them into namespace WebCore, or restore them).

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I reviewed this PR and didn't find any bugs. Because it edits the class and sink generators (which shape every generated wrapper class) across 32 files and I could not run a full build here, a human look would still be worthwhile.

What was reviewed:

  • Grepped src/, packages/, scripts/, test/ for every removed symbol (__ptrOffset, __createWithInitialValues, __createWithValuesAndInitialValues, onStructuredCloneTransfer, JSSink_isSink, BUN_NATIVE_MODULE_START_INDEX, bake_empty_file, hasEventListeners(), offsetOfWrapped, mainWebSocket, renderAbort, highlightColumnEnd, ninjaFile) — no remaining references; ShellBindings.cpp uses the surviving jsvalueArray overload and only JS<Name>Sink::Sink is read.
  • Checked the 66 removed JSBuffer.cpp declarations: definitions precede first use inside namespace WebCore, and the removed lines sat at global scope before line 304.
  • Checked the invokeFunctorPropagatingExceptionIfNecessary pointer-overload removal: all remaining callers pass JSGlobalObject&.
  • Checked the bundler_plugin.h removal: wrapper.h is consumed only by copy_headers.ts, which regenerates headers/ before bindgen; the crate ships pre-generated src/sys.rs and has no build.rs.
Extended reasoning...

Overview

This is a pure deletion sweep: 32 files, +15/-455. It removes unused overloads, extern "C" factories and the __ptrOffset export from generate-classes.ts; unused constants, a createPrototype, a stale extern decl and dead includes from generate-jssink.ts; two never-matching regex rewrites and an unread #define from bundle-modules.ts; an unreachable useThis arrow branch and an impossible "export type" comparison from bundle-functions.ts; write-only pointer metadata from cppbind.ts; 66 global-scope JSC_DECLARE_HOST_FUNCTION prototypes from JSBuffer.cpp; an unused hostName() in WebSocket.cpp; no-arg/ASCIILiteral hasEventListeners overloads; a duplicate pointer overload in JSDOMExceptionHandling.h; unused using aliases; unused TS types in private.d.ts, builtins.d.ts, bake.private.d.ts; write-only fields in the bake client, bun-error, the debug adapter framer, and the build scripts; and a stale committed copy of bundler_plugin.h (now gitignored).

Security risks

None identified. Nothing in the diff touches auth, crypto, TLS, permissions, input parsing, or user-reachable control flow. The only runtime-JS changes are removing a write-only remapped flag and a write-only mainWebSocket singleton in the bake client, and retyping a local in CommonJS.ts from a deleted interface to any without changing the code that uses it.

Level of scrutiny

Moderate. Each removal is individually trivial, but the generator edits multiply across ~94 generated classes and all sink classes, so a single missed reference would be a link/compile failure rather than a runtime bug. I verified by grep that none of the removed C++/extern names have remaining references, that ShellBindings.cpp uses the overload that survives, that every remaining invokeFunctorPropagatingExceptionIfNecessary caller passes a reference, and that each removed JSBuffer.cpp prototype's definition appears before its first use in the hash tables. I could not run bun bd or tsc in this environment, so compile-level confirmation rests on the author's stated verification and CI; that is the main reason for deferring rather than approving.

Other factors

Behavior-preservation checks per REVIEW.md: the bundle-functions.ts useThis constant was hard-coded true, so the emitted text is unchanged; the tokenizer regex at line 105 cannot produce "export type" and no builtin file starts a line with export type; nativeStartIndex remains live for its other consumers; the Config.roots field has no Rust writer in src/runtime/bake. The bun-native-plugin crate consideration from the ruled-out list holds up: wrapper.h is only read by copy_headers.ts after it regenerates headers/, and the crate has no build.rs, so consumers of the published crate use the checked-in src/sys.rs. No tests are added, which is appropriate for a deletion-only change with no behavior to assert.

@robobun

robobun commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the review. On the open point (no build in the review environment): CI compiled and linked this commit on all 13 build lanes (macOS x64 and arm64, Linux glibc, musl and ASAN, Android, FreeBSD, Windows x64 and arm64). A reference to a removed C++ or generated symbol that exists on only one platform would fail one of those lanes, and none did.

The one red test so far, test/bake/deinitialization.test.ts on Alpine aarch64, fails the same way on other open PRs right now (for example builds 118013, 118007 and 118003). This diff does not change the code that test exercises: bake.server.js is byte-identical to main, and the test does not run the client bundle.

JSC_DECLARE_HOST_FUNCTION(constructJSBuffer);
JSC_DECLARE_HOST_FUNCTION(callJSBuffer);

JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_alloc);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

My guess is that we might as well keep these for future use

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

These prototypes cannot serve a future use as written. They are at global scope (line 110 is before namespace Bun { at line 187), so they declare ::jsBufferPrototypeFunction_*. The real functions are WebCore::jsBufferPrototypeFunction_*: every JSC_DEFINE_HOST_FUNCTION for them is inside the namespace WebCore { that opens at line 455, and the binary only has the WebCore:: symbols (nm -C shows WebCore::jsBufferPrototypeFunction_compare(...) and no global one).

So a call through one of these prototypes does not link, and an unqualified use at global scope is ambiguous because of using namespace WebCore; at line 103. The definitions also come before the hash tables that use them, so nothing needs a forward declaration today.

If you want forward declarations in this file, the form that works is inside namespace WebCore. Tell me which you prefer and I will do it: keep the deletion, move them into the namespace, or restore them unchanged.

Jarred-Sumner pushed a commit that referenced this pull request Sep 25, 2026
### Problem
- `hasExportStar` in `src/runtime/bake/hmr-module.ts` has no caller. Its
only call site is a block that #18109 commented out on 2025-03-14. The
`availableExportKeys` local above that block is read only by the
commented-out code.
- `firstConnection` in `src/runtime/bake/client/websocket.ts` is
assigned once and never read.
- No lint reports them. Earlier sweeps ran `tsc --noUnusedLocals` over
`src/js` and `scripts` only, not over `src/runtime/bake`.

### Fix
- Delete `hasExportStar`, the commented-out check,
`availableExportKeys`, and `firstConnection`. 2 files, 40 lines removed.
- Correct because the bundler already drops `hasExportStar`. The
generated `bake.client.js`, `bake.server.js` and `bake.error.js` differ
from `main` only by the two removed local declarations.
- Verified: `tsc -p src/runtime/bake/tsconfig.json --noUnusedLocals` no
longer reports either file. `test/bake/dev/esm.test.ts` (17 pass),
`hot.test.ts` (11 pass) and `bundle.test.ts` (23 pass) with the debug
build.

Behaviour change: none

### Background
- `hmr-module.ts` is the module loader that the dev server sends to the
browser and to the SSR realm. `parseEsmDependencies` walks the
dependency list of an ES module. Each entry carries the export names
that the importer uses.
- The removed check compared those names with the exports of the
dependency and threw a `SyntaxError` for a missing one. It has been off
for 18 months. A missing export fails at the use site.
- A deletion has one possible place, so no other design was weighed.

### Downsides
- The commented-out check was the only sketch of export verification in
the HMR runtime. A person who wants to build it starts from the history
of #18109.

<details><summary>Notes</summary>

#### Why this run is small
Every other hit of this run is live, is platform code with a user on
another target, or is a line that one of the 34 open dead-code pull
requests already deletes. Each removed line here was checked against
those diffs. #40492 and #43378 touch `websocket.ts` in other hunks.

#### Scans of this run, all clean or already claimed
- Debug objects linked again with `--gc-sections --print-gc-sections`,
then `llvm-symbolizer` for `file:line`. 20,668 discarded functions in
bun's objects. The Rust ones outside macros and trait impls are Windows
or macOS helpers, or claimed (#40824, #40557, #40232). The C++ ones are
claimed, are template instantiations, or have a Rust caller on another
target (`bsd_socket_export`, `posix_spawnattr_reset_signals`).
- Rust functions that never get a symbol (generic or `#[inline]`, never
instantiated), found by comparing every `fn` line with the DWARF
declaration lines of all emitted functions. 86 hits outside `cfg`, trait
impls and `#[inline(always)]`. All are Windows-only, test-only (the
outbound half of `api/bun/h2/connection.rs`), or claimed.
- `clang -fsyntax-only -Wunused-function -Wunused-macros
-Wunused-template -Wunused-member-function` over 588 translation units
and the 69 unified ones (the build passes `-Wno-unused-function`). 3
functions and 6 macros.
`formatStackTraceToJSValueWithoutPrepareStackTrace`, `hostName`,
`G_TRUE`, `G_FALSE`, `MAX_LABELS` and `us_ioctl` are claimed (#40367,
#43378, #40492, #40294). `us_quic_send_one` is used under the non-Linux
`#if` branch.
- A whole-program C++ reference index (`c-index-test -index-file`, 657
translation units, 32,018 symbols declared in bun's tree). 8,711 have no
recorded reference. After filters for template-dependent uses, `extern
"C"`, virtual methods and names that WebKit headers use, 78 remain. All
are index artifacts (typedef struct tags, primary templates with used
specializations, `requires` clauses) or one-line getters in files that
open pull requests rewrite.
- `tsc --noUnusedLocals` over `src/js`, `scripts`, `src/codegen`,
`src/runtime/bake`, `src/node-fallbacks` and the sources of each
package. The hits outside this change are claimed (#40122, #41169,
#41385, #40492, #43778) or are loop variables.
- Regex scans for struct fields with no read and for `bool` or `Option`
fields that only ever get one constant. Nothing new after #43745.
- Exports of `src/js` modules and builtin functions with no mention in
another file: none.
- Files that nothing includes, imports or names: none outside `.idl`
copies (#41064). `src/symbols.txt`, `symbols.def` and the `package.json`
scripts name nothing that is gone. No `#if 0`.

</details>

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

---

**no test proof** · iteration 1 · the description declares no behaviour
change, so there is no failing test to prove; the existing suite in CI
is the check

<!-- robobun:evidence:end -->
Jarred-Sumner pushed a commit that referenced this pull request Sep 26, 2026
… and the CI pipeline script (#43976)

Behaviour change: none

### Problem
- Eleven files hold items that nothing reads or calls: write-only
fields, an uncalled method, four unused types, and CI options that are
parsed and dropped.
- No tool reports them. C and C++ have no dead-code lint. TypeScript
counts `x += n` as a read. The Rust types come from a macro.

### Fix
- TypeScript: remove `DataViewReader.u16()`, `DataViewWriter.capacity`,
the `totalCount` local in `updateBuildErrorOverlay`, and a commented-out
block from 2024 in `src/js/node/dgram.ts`.
- C and C++: remove `us_udp_socket_t.connected`,
`us_quic_stream_s.headers_delivered` and `Http2ResponseData::totalSize`
(each is only written), and `#undef FD_BITS` (nothing defines it).
- Rust and CI: remove the opaque types `us_loop_t`,
`us_socket_context_t`, `us_udp_socket_t`, `us_udp_packet_buffer_t` from
`src/uws_sys/lib.rs`. In `.buildkite/ci.ts`, remove `dryRun`,
`Platform.features`, four emoji entries, and the union members
`"amazonlinux"` and `"eol"`.
- Verified: `rg -w` for each symbol over `src`, `packages`, `scripts`,
`test` and `build/debug/codegen` finds no other use. `bun bd`, `bun run
rust:check-all` (12 targets) and `tsc` pass. Self-reviewed: 1 concern
raised, 1 addressed.

### Background
- `DataViewReader` and `DataViewWriter` decode and encode the binary
messages between the dev server and its browser client.
- `us_udp_socket_t` and `us_quic_stream_s` are private C structs of
uSockets. Rust holds them as opaque pointers, so no Rust struct mirrors
their layout.
- `bun_core::opaque_extern!` declares a zero-sized Rust type for a C
struct. Rust code names `Loop`, `udp::Socket` and `udp::PacketBuffer`,
not the four removed types.

### Downsides
- None found. Checked each removed symbol for users in Rust, C, C++,
TypeScript, generated code, tests, and open pull requests.

<details><summary>Notes</summary>

**Evidence per removal**

| Item | Evidence |
| --- | --- |
| `DataViewReader.u16()` | `rg '\.u16\('` over `src/runtime/bake`,
`test/bake`, `test/cli/inspect`: no hit. |
| `DataViewWriter.capacity` | The only hit of `.capacity` in the bake
TypeScript is the assignment in the constructor. `initCapacity` is the
only caller of the constructor. |
| `totalCount` | Two hits: the declaration and one `+=`. |
| `dgram.ts` block | `git blame`: 589f941, 2024-04-26.
`replaceHandle` and `startListening` are not defined in the file. |
| `us_udp_socket_t.connected` | Two hits, both `udp->connected = 0;`. |
| `us_quic_stream_s.headers_delivered` | Two hits in `quic.c`: the field
and one `= 1`. The struct is private to `quic.c`. |
| `Http2ResponseData::totalSize` | One member access: `data.totalSize =
totalSize;`. The other hits of `totalSize` are the function parameter. |
| `#undef FD_BITS` | The only hit of `FD_BITS` in `src` and `packages`.
|
| Four opaque types | Each name has one non-comment hit in all Rust
sources and generated Rust: the macro call. |
| `dryRun` | Four hits in `ci.ts`: the field, two assignments, one
destructure. Nothing reads the binding. |
| `Platform.features` | One hit. |
| Emoji, `Distro`, `Tier` entries | No platform in `ci.ts` or image in
`scripts/build/ci-images/spec.ts` carries them. `Emoji` is `keyof typeof
emojiMap`, so a remaining caller would fail `tsc -p
scripts/tsconfig.json`. It passes. |

**Taken out because an open pull request uses or removes the item**

- `DataViewWriter.u8()`: dead on main, but #42075 adds its first caller
(`check.u8(IncomingMessageId.check_errors)` in `hmr-runtime-error.ts`).
Git merges the two without a conflict, so the method stays. The tree
that results from a merge of this branch with #42075 has no type error
for `u8`.
- `declare module "bun:wrap"` in `bake.private.d.ts`: no importer, but
#39488 already has the same hunk.

**Tests run with the debug build, all pass**

`test/js/bun/udp/udp_socket.test.ts` (218),
`test/js/bun/udp/dgram.test.ts` (62),
`test/js/bun/http/serve-http2.test.ts` (93),
`test/js/bun/http/serve-http3.test.ts` (73),
`test/bake/dev/bundle.test.ts` (23), `test/bake/dev/esm.test.ts` (17),
`test/bake/hmr-socket-protocol.test.ts` (4),
`test/cli/inspect/BunFrontendDevServer.test.ts` (7).
`test/js/node/dgram/node-dgram.test.js` passes 3 of 4: the IPv6
multicast test fails with `ENODEV` in the test container, with and
without this change. `prettier` and `cargo fmt --check` report no
change.

**Overlap with open pull requests**

Each removed line was compared with the diffs of the 35 open dead-code
pull requests. None removes the same lines. Five files are also touched
by an open pull request, in hunks more than 6 lines away: `internal.h`
and `quic.c` (#40294, #42431), `dgram.ts` (#42431), `overlay.ts`
(#43378, #42075, #39488), `src/uws_sys/lib.rs` (#43010). The added lines
of the 122 open pull requests that were updated since 2026-09-18 and
touch the bake, uSockets, uWS, uws_sys, server, socket or CI sources
name none of the removed symbols.

**What was scanned**

- C and C++: the debug binary was linked a second time with
`--gc-sections`, and the two symbol tables were compared. 414 functions
in bun's own C and C++ are unreachable on Linux. Open pull requests
remove 263 of them. The remainder is in the list below, has a caller on
Windows or macOS, or comes from a macro.
- Rust: 37 `#[no_mangle]` exports are unreachable in the Linux link.
Each has a caller on another platform, or #40824, #40232 or #40557
removes it. A count of references for all 58,055 Rust definitions found
no other item without a user. Of the 144 `allow` attributes for the
unused and unreachable lints, each covers code that depends on `cfg` or
is macro output.
- Cargo: five dependency edges are unused on all 12 targets. #40294
removes three. `bun_resolver -> bun_zstd` is used under
`cfg(bun_codegen_embed)`. `bun_wyhash -> bstr` is used by unit tests.
- Preprocessor: `USE(BIGINT32)` and `ENABLE(MALLOC_BREAKDOWN)` are never
true. #43644 and #40557 remove those branches.
- Also scanned and clean: `src/js`, `src/node-fallbacks`, `src/codegen`,
`scripts/`, `misctools/`, `patches/` (every patch file has a user),
`packages/` except `bun-types`.

**Probably dead, left alone on purpose**

- The `PerformanceResourceTiming` cluster under
`src/jsc/bindings/webcore` (about 2,000 lines:
`PerformanceResourceTiming`, `PerformanceServerTiming`,
`ResourceTiming`, `NetworkLoadMetrics`, `ResourceLoadTiming`,
`ServerTiming` and the two JS wrappers). The linker drops every
constructor, so no instance can exist. The two globals are public and
`test/js/web/web-globals.test.js` checks them. This needs a decision:
keep it for a future resource-timing implementation, or reduce it to the
two constructors.
- `WEBCORE_GENERATED_CONSTRUCTOR_GETTER` (`ZigGlobalObject.cpp`) emits
an `X_getter` function for 50 classes. 45 have no user. A removal needs
a second macro and saves no source lines.
- The WebIDL converters for `byte`, `short` and `long long`, and most
`Clamp` and `EnforceRange` specializations in `JSDOMConvertNumbers.cpp`.
No binding uses them, but `src/codegen/bindgen.ts` maps `t.i8`, `t.i16`
and `t.i64` to them.
- `src/js/bun/sql.ts`: the export properties `sql`, `Query`, `postgres`
and the four error classes. Native code reads only `default` and `SQL`.
It is not certain that no loader path exposes the module object.
- `us_nq_settings_set_scid_len` and `us_nq_settings_set_delay_onclose`
(`node_quic_shim.c`, declared in `src/lsquic_sys/lib.rs`): no caller.
`node:quic` is under active work.
- `Event::currentTargetIsInShadowTree()` and its bit: no reader. The
lines sit next to a hunk of #39929.
- Bake client: `WebSocketWrapper.close()` and `[Symbol.dispose]()`,
`streamingStarted`, the `line` and `column` bookkeeping and seven enum
members in `JavaScriptSyntaxHighlighter.ts`, and `externals` in
`src/node-fallbacks/build-fallbacks.ts`. Each sits next to a hunk of
#43378, #40492, #40122 or #41385.
- The `internal: true` property option of the class generator. A guard
throws on it, so the branches behind it cannot run. Five open pull
requests touch `generate-classes.ts`.
- `H2App::getNativeHandle` (next to a hunk of #41195) and
`uws_app_listen_config_t` (its last user goes with #42431).
- `UWS_ALLOW_SHARED_AND_DEDICATED_COMPRESSOR_MIX`,
`UWS_ALLOW_8_WINDOW_BITS` and `LIBUS_NO_SSL`: never defined, but they
are documented opt-in switches of the upstream libraries.
- `scripts/debug-coredump.ts`, `scripts/gamble.ts`,
`scripts/github-metrics.ts`, `scripts/lldb-inline.sh` with
`scripts/lldb-inline-tool.cpp`, and `packages/h3blast`: nothing
references them. They read as tools that a person runs by hand.
- #40232 removes `napi_internal_get_version`. #42556 renamed that
function to `Bun__napi_get_version` on main, and it still has no caller.

</details>

This branch has not been deployed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants