Repository navigation
Conversation
|
Warning Review limit reached
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 detailsLimit details: You’ve used all 5 included reviews currently available. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (68)
Comment |
|
Status: the diff is ready for review. The second commit adds a bunfig test in 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:
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. |
|
Updated 7:24 PM PT - Aug 26th, 2026
❌ @robobun, your commit 15e9fcd has 2 failures in
🧪 To try this PR locally: bunx bun-pr 40525That installs a local version of the PR into your bun-40525 --bun |
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.
97b6ff9 to
430c82a
Compare
…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>
… 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>
Problem
RELEASE_ASSERTis commented out, IDL converters for types no binding declares, and IPCencode/decodetemplates with noEncodertype in the tree.dead_codelint exempts trait impls andpubitems. A whole-workspace analysis over the 11 shipped targets plus a--gc-sectionslink of the debug build show a set of trait impls, error variants, and config fields that nothing reaches.Fix
rgoversrc/,packages/,scripts/, andbuild/debug/codegen/, including the#[cfg(windows)]and macOS paths. The Notes list each symbol.#[cfg(debug_assertions)]path, or a unit test still needs were left alone (also listed in the Notes).bun bd, thenbun bd teston the newinstall.lockfilebunfig test intest/cli/install/bun-install.test.ts(a bunfig with the droppedpath/savePathkeys still installs and writesbun.lock) and on the abort, message channel and event, structured clone, broadcast channel, performance, worker transfer,fs.watch, bundler naming,import.meta, WebSocket, URL andbun runbunfig tests (16 files, 0 failures).bun run rust:check-allpasses on all 12 targets,cargo clippy --workspaceandcargo fmt --checkare clean.src/jsc/Cargo.toml,src/paths/Cargo.toml,Cargo.lock), so whichever lands second needs a small rebase.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 remainingexternvtable declarations andif constexprbodies compile to nothing.Converter<IDLType>/JSConverter<IDLType>are the template specializations the generated bindings call throughconvert<IDLType>(...). A specialization for a type no binding names is never instantiated.dead_codeandunreachable_pub, so apubitem 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_INTEGRITYblocks (extern vtable declarations plus theif constexpr (std::is_polymorphic_v<T>)body intoJSNewlyCreated) inJSAbortSignal.cpp,JSBroadcastChannel.cpp,JSMessageEvent.cpp,JSMessagePort.cpp,JSPerformanceMark.cpp. EveryRELEASE_ASSERT(actualVTablePointer == expectedVTablePointer)in these files was a comment.IDLFloatandIDLUnrestrictedFloat(JSDOMConvertNumbers.h),IDLCallbackInterface<T>(JSDOMConvertCallbacks.h),IDLRequiresExistingAtomStringAdaptor<T>(JSDOMConvertStrings.h),IDLDataViewandIDLAllowSharedAdaptor<T>with theBufferSourceConverterAllowSharedMode::Allowbranch (JSDOMConvertBufferSource.h). The IDL type definitions inIDLTypes.hstay.EventInit::encode/decode(EventInit.h),BufferSource::encode/decode(BufferSource.h): noIPC::Encoder/Decoderexists in Bun.CallbackResult<ReturnType>primary template members (CallbackResult.h): every use isCallbackResult<void>. The<wtf/Expected.h>include went with them.SerializedScriptValue:convert(), the write-onlyCloneDeserializer::m_isDOMGlobalObject, them_blobURLs/m_blobFilePathsmembers nothing read, their constructor anddeserializeparameters, and thedeserialize(..., blobURLs, blobFilePaths, ...)overload. The two publicdeserializesignatures other files call are unchanged.MessagePort::started(),root(MessagePort*)(and theWebCoreOpaqueRootforward declaration and include only it used),EventListenerMap::lock(),IdentifierEventListenerMap::entries()/lock(),EventEmitter::eventTargetDataConcurrently(), sixTaskSourceenumerators (queueTaskInEventLoopignores the value), the#if ENABLE(OFFSCREEN_CANVAS)include inJSEventTargetCustom.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.hnow includesJSBuffer.hdirectly.SecretKeyJobCtx::result()(CryptoKeygen.h), unusedNodeVMSourceTextModule::cachedExecutable(), unusedJSNodeTypeconstant (JSDOMWrapper.h).Removed, Rust:
Default for FrameHeader(bun_http_types),Default for HeaderandDisplay for Request(bun_picohttp),Display for EStringandDisplay for expr::Tag(bun_ast),Display for PathTemplate/PathTemplateConstandPathTemplateConst::printthat only they called (bun_bundler),Display for ConsoleObject,Display for PathOrFileDescriptor,Display for UUID5/UUID7with theirto_uuidhelpers (bun_jsc),Display for InvalidDateand theErrorimpl that required it (bun_core),From<ToUTF16Error>andFrom<InlinedError>forbun_core::Errorwith theStringTooLongvariant only the latter constructed,Debug for S3UploadResult(bun_runtime),From<&[u8]> for StringOrBytesToDecode(bun_runtime),ErrName for Errorinbun_http_jsc,bun_s3_signing(each with the privatename()only the impl called) andbun_sql.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::Certloses its unused#[from](it is constructed by name).TransformOptions::{serve, no_summary, disable_hmr, inject, serve_splitting}(bun_options_types) with their writers inJSTranspiler.rsandjs_bundle_completion_task.rsand theserve_splittingbranch inHTMLBundle.rsthat could never run,BunInstall::{lockfile_path, save_lockfile_path}with the[install.lockfile] path/savePathparser blocks inbunfig.rs(not documented, not tested, never read).pubitems:E::{ECHILD, EWOULDBLOCK, EOPNOTSUPP, EINPROGRESS}and the Windowsposix::{mode_t, E}aliases (bun_errno),WindowsLoop::{wake, wait, unref}(bun_uws_sys),PackageJsonView::source_pathand its impl (bun_install_types,bun_resolver),StreamPriorityreduced to theBYTE_SIZEconstant that is its only use (bun_http_types), thenode::Bufferre-export, and unused re-exports inbun_install(lib.rs,PackageManager.rs: only the names leave thepub uselists, the functions stay).scopeguard,enum-map,enumset,bitflagsinbun_paths;bun_patchinbun_jsc.src/js/builtins/shell.ts: a commented-outsetImmediate(autoStartShell, ...)line;autoStartShelldoes 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)]);AsyncCallTypeandtty::Modevariants (#[repr]mirrors of C++ enums);host_fn_this_value(emitted bygenerate-classes.tsforpassThiswithoutsharedThis);Flags::Fifo(inserted by four runtime files, never read);bun_core::strings::split_once/rsplit_once(named inclippy.toml);braces::Tokenimpls (unit tests);src/runtime/api/bun/h2/*(in progress,#![allow(dead_code)]by design); allpubfields inbun_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,PerformanceServerTimingand their wrappers are never constructed (Performance::markResourceTimingis 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 866dead_publicfindings 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-sectionslisted 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++ undersrc/jsc/bindingswere 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