Skip to content

Remove dead code from the WebCore bindings and 20 Rust crates - #40525

Open
robobun wants to merge 5 commits into
mainfrom
farm/ff4b9f9a/dead-code-sweep
Open

robobun wants to merge 5 commits into
mainfrom
farm/ff4b9f9a/dead-code-sweep

Conversation

@robobun

@robobun robobun commented Aug 26, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • The WebCore-derived bindings still carry WebKit machinery Bun never instantiates: vtable checks whose RELEASE_ASSERT is commented out, IDL converters for types no binding declares, and IPC encode/decode templates with no Encoder type in the tree.
  • On the Rust side, rustc's dead_code lint exempts trait impls and pub items. A whole-workspace analysis over the 11 shipped targets plus a --gc-sections link of the debug build show a set of trait impls, error variants, and config fields that nothing reaches.

Fix

Background

  • ENABLE(BINDING_INTEGRITY) is WebKit's check that a wrapped C++ object has the vtable its IDL interface expects. Bun commented out the assertion in 2022, so the remaining extern vtable declarations and if constexpr bodies compile to nothing.
  • Converter<IDLType> / JSConverter<IDLType> are the template specializations the generated bindings call through convert<IDLType>(...). A specialization for a type no binding names is never instantiated.
  • The workspace denies dead_code and unreachable_pub, so a pub item that nothing uses is only visible to a cross-crate analysis, and an unused trait impl only to the linker.
Notes

Removed, C++ (src/jsc/bindings/webcore/ unless noted):

  • BINDING_INTEGRITY blocks (extern vtable declarations plus the if constexpr (std::is_polymorphic_v<T>) body in toJSNewlyCreated) in JSAbortSignal.cpp, JSBroadcastChannel.cpp, JSMessageEvent.cpp, JSMessagePort.cpp, JSPerformanceMark.cpp. Every RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer) in these files was a comment.
  • Converter specializations: IDLFloat and IDLUnrestrictedFloat (JSDOMConvertNumbers.h), IDLCallbackInterface<T> (JSDOMConvertCallbacks.h), IDLRequiresExistingAtomStringAdaptor<T> (JSDOMConvertStrings.h), IDLDataView and IDLAllowSharedAdaptor<T> with the BufferSourceConverterAllowSharedMode::Allow branch (JSDOMConvertBufferSource.h). The IDL type definitions in IDLTypes.h stay.
  • EventInit::encode/decode (EventInit.h), BufferSource::encode/decode (BufferSource.h): no IPC::Encoder/Decoder exists in Bun.
  • CallbackResult<ReturnType> primary template members (CallbackResult.h): every use is CallbackResult<void>. The <wtf/Expected.h> include went with them.
  • SerializedScriptValue: convert(), the write-only CloneDeserializer::m_isDOMGlobalObject, the m_blobURLs / m_blobFilePaths members nothing read, their constructor and deserialize parameters, and the deserialize(..., blobURLs, blobFilePaths, ...) overload. The two public deserialize signatures other files call are unchanged.
  • MessagePort::started(), root(MessagePort*) (and the WebCoreOpaqueRoot forward declaration and include only it used), EventListenerMap::lock(), IdentifierEventListenerMap::entries() / lock(), EventEmitter::eventTargetDataConcurrently(), six TaskSource enumerators (queueTaskInEventLoop ignores the value), the #if ENABLE(OFFSCREEN_CANVAS) include in JSEventTargetCustom.cpp (the header does not exist in Bun).
  • src/jsc/bindings/JSDOMConvertBufferSource+JSBuffer.h: an include-only header with an empty namespace since 2023. JSDOMConvert.h now includes JSBuffer.h directly.
  • Declaration-only SecretKeyJobCtx::result() (CryptoKeygen.h), unused NodeVMSourceTextModule::cachedExecutable(), unused JSNodeType constant (JSDOMWrapper.h).

Removed, Rust:

  • Trait impls nothing calls: Default for FrameHeader (bun_http_types), Default for Header and Display for Request (bun_picohttp), Display for EString and Display for expr::Tag (bun_ast), Display for PathTemplate / PathTemplateConst and PathTemplateConst::print that only they called (bun_bundler), Display for ConsoleObject, Display for PathOrFileDescriptor, Display for UUID5 / UUID7 with their to_uuid helpers (bun_jsc), Display for InvalidDate and the Error impl that required it (bun_core), From<ToUTF16Error> and From<InlinedError> for bun_core::Error with the StringTooLong variant only the latter constructed, Debug for S3UploadResult (bun_runtime), From<&[u8]> for StringOrBytesToDecode (bun_runtime), ErrName for Error in bun_http_jsc, bun_s3_signing (each with the private name() only the impl called) and bun_sql.
  • Error variants nothing constructs: bun_jsc::Error::{Watcher, Ast, Patch, Url, Paths}, bun_http::Error::Core, bun_spawn::Error::Core, bun_js_parser::Error::Core, bun_bundler::Error::OptionsTypes, bun_resolver::Error::{MissingResolveDir, InvalidResolveDir} with two stale commented-out blocks that named them, EncodeError::OutOfMemory / DecodeDataError::OutOfMemory (bun_resolver::data_url), bun_parsers::Error::{UTF8Fail, UnexpectedSyntax, JSONStringsMustUseDoubleQuotes}. bun_http::Error::Cert loses its unused #[from] (it is constructed by name).
  • Write-only config fields: TransformOptions::{serve, no_summary, disable_hmr, inject, serve_splitting} (bun_options_types) with their writers in JSTranspiler.rs and js_bundle_completion_task.rs and the serve_splitting branch in HTMLBundle.rs that could never run, BunInstall::{lockfile_path, save_lockfile_path} with the [install.lockfile] path / savePath parser blocks in bunfig.rs (not documented, not tested, never read).
  • Unused pub items: E::{ECHILD, EWOULDBLOCK, EOPNOTSUPP, EINPROGRESS} and the Windows posix::{mode_t, E} aliases (bun_errno), WindowsLoop::{wake, wait, unref} (bun_uws_sys), PackageJsonView::source_path and its impl (bun_install_types, bun_resolver), StreamPriority reduced to the BYTE_SIZE constant that is its only use (bun_http_types), the node::Buffer re-export, and unused re-exports in bun_install (lib.rs, PackageManager.rs: only the names leave the pub use lists, the functions stay).
  • Unused dependencies: scopeguard, enum-map, enumset, bitflags in bun_paths; bun_patch in bun_jsc.
  • src/js/builtins/shell.ts: a commented-out setImmediate(autoStartShell, ...) line; autoStartShell does not exist.

Left alone on purpose (found by the analysis, verified live or intentional): StoredTrace, dump_stack_trace, dump_current_stack_trace, debug_flags::has_resolve_breakpoint, ntstatus::*, ArrayHashMap::unlock_pointers, TaskTag::name (all used under #[cfg(debug_assertions)]); AsyncCallType and tty::Mode variants (#[repr] mirrors of C++ enums); host_fn_this_value (emitted by generate-classes.ts for passThis without sharedThis); Flags::Fifo (inserted by four runtime files, never read); bun_core::strings::split_once / rsplit_once (named in clippy.toml); braces::Token impls (unit tests); src/runtime/api/bun/h2/* (in progress, #![allow(dead_code)] by design); all pub fields in bun_windows_sys, bun_boringssl_sys, bun_cares_sys, bun_libuv_sys (C struct layouts); the FFI and IDL type definitions the removed converters referenced.

Possible larger follow-up for a maintainer decision: PerformanceResourceTiming, ResourceTiming, NetworkLoadMetrics, PerformanceServerTiming and their wrappers are never constructed (Performance::markResourceTiming is a TODO stub), about 1.3k lines. The JS constructors are web-visible globals, so removing the implementation changes the global surface. Not in this PR.

Method: hawk (the cross-crate analysis from hawk.toml, all 11 targets, --only dead-public) reported 866 dead_public findings on this base; 545 sit in files the open PRs already edit and 286 of the rest are C struct fields. A relink of the debug build with --gc-sections --print-gc-sections listed the unreferenced trait methods. A separate read of the WebCore headers found the template and macro items a link pass cannot see. src/install, src/runtime/node, src/runtime/shell, src/shell_parser, src/sql, src/http, src/runtime/api, src/runtime/webcore, src/runtime/server, 34 small crates, src/js/**, and the non-WebCore C++ under src/jsc/bindings were scanned symbol by symbol and came back clean apart from what is listed here.


no test proof · iteration 1 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/cli/install/bun-install.test.ts

@coderabbitai

coderabbitai Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

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

Or wait 6 minutes for your next included review.

View limit details

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

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7f6da344-f811-4efa-a093-095e8370fb0c

📥 Commits

Reviewing files that changed from the base of the PR and between 0e395c2 and 15e9fcd.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (68)
  • src/ast/e.rs
  • src/ast/expr.rs
  • src/bun_core/error.rs
  • src/bun_core/string/SmolStr.rs
  • src/bun_core/string/immutable.rs
  • src/bun_core/wtf.rs
  • src/bundler/error.rs
  • src/bundler/options.rs
  • src/bunfig/bunfig.rs
  • src/errno/windows_errno.rs
  • src/http/error.rs
  • src/http_jsc/error.rs
  • src/http_types/h2.rs
  • src/install/PackageManager.rs
  • src/install/lib.rs
  • src/install_types/resolver_hooks.rs
  • src/js/builtins/shell.ts
  • src/js_parser/error.rs
  • src/jsc/Cargo.toml
  • src/jsc/ConsoleObject.rs
  • src/jsc/bindings/JSDOMConvertBufferSource+JSBuffer.h
  • src/jsc/bindings/JSDOMWrapper.h
  • src/jsc/bindings/NodeVMSourceTextModule.h
  • src/jsc/bindings/node/crypto/CryptoKeygen.h
  • src/jsc/bindings/webcore/BufferSource.h
  • src/jsc/bindings/webcore/CallbackResult.h
  • src/jsc/bindings/webcore/EventEmitter.h
  • src/jsc/bindings/webcore/EventInit.h
  • src/jsc/bindings/webcore/EventListenerMap.h
  • src/jsc/bindings/webcore/IdentifierEventListenerMap.h
  • src/jsc/bindings/webcore/JSAbortSignal.cpp
  • src/jsc/bindings/webcore/JSBroadcastChannel.cpp
  • src/jsc/bindings/webcore/JSDOMConvert.h
  • src/jsc/bindings/webcore/JSDOMConvertBufferSource.h
  • src/jsc/bindings/webcore/JSDOMConvertCallbacks.h
  • src/jsc/bindings/webcore/JSDOMConvertNumbers.h
  • src/jsc/bindings/webcore/JSDOMConvertStrings.h
  • src/jsc/bindings/webcore/JSEventTargetCustom.cpp
  • src/jsc/bindings/webcore/JSMessageEvent.cpp
  • src/jsc/bindings/webcore/JSMessagePort.cpp
  • src/jsc/bindings/webcore/JSPerformanceMark.cpp
  • src/jsc/bindings/webcore/MessagePort.cpp
  • src/jsc/bindings/webcore/MessagePort.h
  • src/jsc/bindings/webcore/SerializedScriptValue.cpp
  • src/jsc/bindings/webcore/SerializedScriptValue.h
  • src/jsc/bindings/webcore/TaskSource.h
  • src/jsc/error.rs
  • src/jsc/node_path.rs
  • src/jsc/uuid.rs
  • src/options_types/schema.rs
  • src/parsers/error.rs
  • src/paths/Cargo.toml
  • src/picohttp/lib.rs
  • src/resolver/data_url.rs
  • src/resolver/error.rs
  • src/resolver/package_json.rs
  • src/resolver/resolver.rs
  • src/runtime/api/JSTranspiler.rs
  • src/runtime/api/js_bundle_completion_task.rs
  • src/runtime/node.rs
  • src/runtime/node/node_fs_watcher.rs
  • src/runtime/server/HTMLBundle.rs
  • src/runtime/webcore/s3/simple_request.rs
  • src/s3_signing/crate_error.rs
  • src/spawn/error.rs
  • src/sql/error.rs
  • src/uws_sys/Loop.rs
  • test/cli/install/bun-install.test.ts

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

@robobun

robobun commented Aug 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

Status: the diff is ready for review. The second commit adds a bunfig test in test/cli/install/bun-install.test.ts: a [install.lockfile] section with the dropped path / savePath keys still installs and writes bun.lock. Local verification: bun bd builds, bun bd test passes on that test and the 16 test files named in the description, bun run rust:check-all passes on all 12 targets, clippy and rustfmt are clean.

CI (build 106541): 178 of 181 jobs pass. The three red jobs are two tests that fail the same way on main and that this diff does not touch:

  • test/cli/run/require-cache.test.ts on Windows x64 and Linux x64 ASAN ("Memory leak detected" in via require() with a lot of function calls, a timeout in via import()). It fails on main in builds 106466, 106385, 106344, 106201, 106100, 106068 and 105838. This diff does not touch module loading or the transpiler.
  • test/js/web/url/url.test.ts on macOS x64 (special-scheme hosts use the Unicode 16 IDNA table, an ICU table difference on those agents). It fails on main in builds 106512, 106466 and 106385. This diff does not touch URL parsing.

Both are reported as main breaks. The other entries in the build summary passed on retry or alone. A retrigger cannot turn the macOS x64 lane green, so none was pushed.

Comment thread src/install/PackageManager.rs Resolved
Comment thread src/http_types/h2.rs Resolved
Comment thread src/errno/windows_errno.rs Resolved
Comment thread src/http_types/h2.rs Resolved
@robobun

robobun commented Aug 26, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 7:24 PM PT - Aug 26th, 2026

❌ @robobun, your commit 15e9fcd has 2 failures in Build #106541 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 40525

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

bun-40525 --bun

Comment thread test/cli/install/bun-install.test.ts Resolved

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

Code review found no issues

No high-confidence issues detected in this change.

Delete items that nothing in the shipped binary reaches on any of the 11
build targets: no-op BINDING_INTEGRITY vtable checks, IDL converter
specializations that are never instantiated, WebKit IPC encode/decode
templates, unused trait impls, error variants nothing constructs, and
write-only config fields. 68 files, +32 / -916.
The install.lockfile.path and savePath keys were parsed into fields
nothing read. The parser no longer stores them, and this pins that a
bunfig.toml with those keys still installs and writes bun.lock.
@robobun
robobun force-pushed the farm/ff4b9f9a/dead-code-sweep branch from 97b6ff9 to 430c82a Compare August 27, 2026 01:45

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

Code review found no issues

No high-confidence issues detected in this change.

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 25, 2026
… the build scripts (#43778)

### Problem
- A few C++ and TypeScript items have no caller, no producer, or no
effect.
- `BUN_MESSAGEPORT_USES_PIPE` (`src/jsc/bindings/webcore/MessagePort.h`)
is always `1`. The `#if` around all of `MessagePortPipe.cpp` never
excludes anything.

### Fix
- WebView: remove `WebViewProto::Reader::u16()` and `f32()`
(`ipc_protocol.h`), which have no caller. Remove the CDP `Method` values
`RuntimeEnable`, `TargetCloseTarget` and `InputDispatchScrollEvent` with
their `case` labels (`ChromeBackend.{h,cpp}`). No pending entry carries
them.
- WebCore bindings: remove the `BUN_MESSAGEPORT_USES_PIPE` define and
guard, the self-alias of `ExtendedDOMClientIsoSubspaces`, the forward
declaration of `URLPatternUtilities::URLPatternInit` (no such type), the
enumerators `PerformanceEntry::Type::Paint` and
`CastedThisErrorBehavior::ReturnEarly`, and 13 lines of commented-out
WebKit code.
- Build scripts: remove `getBuildNumber()` (`.buildkite/ci.ts`) and
`BunOutput.rustObjects` (`scripts/build/bun.ts`). Nothing reads either.
- Verified: `rg -w` for each symbol over `src`, `packages`, `scripts`,
`test` and `build/debug/codegen` finds no other use. `bun bd` passes.
The Notes list the tests.

### Background
- `ipc_protocol.h` is the wire format between bun and the WebView host
process. `Reader` decodes frames. Every caller uses `u8`, `u32`, `bytes`
and `str` only.
- `ChromeBackend` tags each pending Chrome DevTools Protocol command
with a `Method`, so that the response handler knows which promise to
settle. A value that no pending entry carries cannot reach the `switch`.
- #29937 added the guard so that `MessagePortPipe.cpp` compiled to
nothing while a verification step reverted `MessagePort.h`. Both files
are on main now.

### Downsides
- None found. Checked each removed symbol for users in C++, Rust,
generated code and `src/symbols.*`. The removed enum values are
in-memory tags or template arguments. Rust mirrors neither enum.

<details><summary>Notes</summary>

Smoke tests with the debug build, all pass:
`test/js/web/workers/message-port-pipe.test.ts`,
`message-channel.test.ts`, `performance-observer-leak.test.ts`,
`test/js/node/perf_hooks/perf_hooks.test.ts`, `test/js/web/urlpattern/`,
`test/js/bun/webview/webview-chrome-pipe.test.ts`. `clang-format` and
`prettier` report no change on the touched files. `.buildkite/ci.ts`
still transpiles.

Each removal was checked against the diffs of the 34 open dead-code PRs.
None of them removes the same lines. `MessagePort.h` is also touched by
#40525, in a different hunk.

How the Rust side was scanned, and why this PR has no Rust in it:
- `cargo mordant` at the revision pinned in
`.github/workflows/rust-lints.yml`, over the Linux, Windows and macOS
targets, with the `unused_pub` entries taken out of the baseline. It
reports 188 `pub` items that nothing in the workspace uses. Every
function, method and struct in that list is in one of four groups: an
open PR already removes it, a `cfg` that the run does not build uses it
(`bun_zstd::inflate_embedded*` under `bun_codegen_embed`,
`StoredTrace::from` in `PackageInstall.rs`), only a unit test uses it
(`CowSliceZ::init_dupe`), or #42119 left it on purpose
(`host_fn_this_value`, `host_fn_setter`, `JsClass::estimated_size`). The
constants are flag, errno and syscall-tag tables.
- A rust-analyzer SCIP index for five targets (Linux, Windows, macOS,
FreeBSD, Android) plus a reachability closure over it. Two blind spots
make it unreliable alone: rust-analyzer sets `cfg(test)` by default,
which hides `src/runtime/bin_entry`, and references that come from a
`macro_rules!` body are not indexed (`comptime_string_map!`, the CSS
`to_css` bridges). With those corrected, it agrees with mordant and adds
nothing.
- Cargo's own `unused_dependencies` warnings: 9 edges. Each is used on
another target, or #40294 already removes it.
- Rust files outside every module tree: none. Headers that nothing
includes: none (the remaining ones come in through
`GeneratedJS2Native.h`, `NativeModuleImpl.h` or `include_bytes!`).

Also scanned and clean: `src/js/{node,internal,bun,thirdparty}` and
`src/js/builtins` (all 50 builtins and all 177 private names have a
user), `scripts/`, `misctools/`, `.buildkite/ci.ts`, and the C++ under
`webcore/`, `webcrypto/`, `node/` and `src/runtime/` that no open PR
touches.

Probably dead, left alone on purpose:
- `bun_core::strings::split_once` (`src/bun_core/string/immutable.rs`):
no caller on any target. It sits next to the hunk in which #40824
removes `rsplit_once`, so a removal here would conflict with that PR.
- The raw-list `myersDiff` export of
`src/js/internal/assert/myers_diff.ts` and the `Output::List` path
behind it in `src/runtime/node/node_assert.rs` (about 115 lines):
nothing consumes it. #39924 kept the export on purpose, and Node's own
`test-assert-myers-diff.js` needs it if that test is vendored.
- `BuiltinName::{redirect, asyncIterator, name, default, fatal,
ignoreBOM}` (`src/jsc/lib.rs`, mirrored by position in `bindings.cpp`):
never constructed. A removal conflicts with #40232.
- `FetchHeaders` guard handling (`removePrivilegedNoCORSRequestHeaders`
and the `Guard::Immutable` checks): every construction site passes
`Guard::None`, and #43644 removes `setGuard`. This is unreachable code,
not unreferenced code.
- `ServerTiming`'s constructor and its `durationSet` / `descriptionSet`
fields: nothing constructs a `ServerTiming`. #40122 and #41385 touch the
same cluster.
- The `$isPromiseFulfilled`, `$isPromiseRejected` and `$alwaysInline`
codegen macros: no user since 92459cd.
- `scripts/build/config.ts` flags `logs` and `baseline`: parsed and
printed, never read since the Rust rewrite.
`NestedCmakeBuild.{extraCFlags, extraCxxFlags, libSubdir, sourceSubdir,
pic}`: no dependency sets them, but `scripts/build/deps/README.md`
documents them as the API for future dependencies.
- `misctools/gen-unicode-table.ts` and `unicode-generator.ts` emit Zig.
Nothing references them, but `src/bun_core/string/identifier.rs` still
names the generator as the way to rebuild its tables.
- `completions/bun-cli.json` and
`misctools/generate-cli-completions.ts`: nothing in the repository reads
the JSON. It is still updated by hand, so something outside the
repository may use it.

</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