Skip to content

Remove dead code from Exception.h, ExceptionOr.h, ErrorCode.h, InspectorHTTPServerAgent.cpp, and JSBuffer.cpp - #45725

Open
robobun wants to merge 1 commit into
mainfrom
robobun/432995c1/dead-code-sweep
Open

robobun wants to merge 1 commit into
mainfrom
robobun/432995c1/dead-code-sweep

Conversation

@robobun

@robobun robobun commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

Behaviour change: none

Problem

  • Five declarations in src/jsc/bindings have no reference. No tool reports them. A name search and a read of the code found them.
  • Two are the free functions isolatedCopy(Exception&&) and isolatedCopy(ExceptionOr<void>&&). WebKit deleted the same two in 2022 (WebKit/WebKit@5b8ad34f804c).

Fix

  • Delete the two free isolatedCopy functions together. isolatedCopy(Exception&&) goes because its one caller goes in the same change.
  • Delete ErrorCodeCache::Field, the typedefs RouteId and RequestId, and JSBuffer::typeRange.
  • Verified: bun bd links. bun bd test passes for test/js/node/buffer.test.js (718 tests), test/cli/inspect/HTTPServerAgent.test.ts (1) and test/js/web/crypto/web-crypto.test.ts (95).
  • Self-reviewed: 41 concerns raised, 36 addressed. The Notes block names the five that are not.

Background

  • Exception and ExceptionOr are Bun's copies of WebCore's error types. WTF::CrossThreadCopier copies a value for another thread through the member isolatedCopy(), which stays.
  • ErrorCodeCache caches one error structure per Node error code in its internal fields. ErrorCode.cpp indexes them with static_cast<unsigned>(code), not through Field.
  • CREATE_METHOD_TABLE reads JSCastingHelpers::InheritsTraits<JSBuffer>::typeRange, not a member of the class. So JSBuffer::typeRange has no effect.
  • No other design applies: each change deletes an unreferenced declaration.

Downsides

Notes

Removed, with the check for each (all run on this branch):

  • src/jsc/bindings/ExceptionOr.h: isolatedCopy(ExceptionOr<void>&&). git grep -P '(?<![.>\w~])isolatedCopy\s*\(\s*[^)\s]' -- src packages finds no call of a free isolatedCopy.
  • src/jsc/bindings/Exception.h: isolatedCopy(Exception&&). Its one caller was the function above. Keep both deletions or neither: with only the ExceptionOr.h function restored, its call binds to itself through the ExceptionOr(Exception&&) constructor.
  • src/jsc/bindings/ErrorCode.h: using Field = ErrorCode; in ErrorCodeCache. git grep 'ErrorCodeCache::Field' -- src finds nothing.
  • src/jsc/bindings/InspectorHTTPServerAgent.cpp: typedef int RouteId; and typedef int RequestId;. git grep -w -E 'RouteId|RequestId' -- 'src/*.cpp' 'src/*.h' finds nothing else. They belong to HTTP server request events that the agent never sends. Remove dead code from the inspector agent, the WebKit IDL copies, and an orphaned package #41064 has the five uncalled methods above them (requestWillBeSent to requestHandlerException). This change adds no conflict to it.
  • src/jsc/bindings/JSBuffer.cpp: JSBuffer::typeRange. git grep -w typeRange -- src finds only the InheritsTraits specializations in JSEventCustom.h and Bindgen/JSWrapper.h.

Open pull requests, checked on 2026-10-17 09:47 UTC, directly before the push:

  • All 5,530 open heads were fetched over git. 46 touch one of the five files.
  • No open pull request deletes one of these declarations. No added line in any of them uses a removed name.
  • git merge-tree of each of the 46 against main and against this branch shows one new conflicted file: Exception.h in Headers: throw instead of aborting when a value passes the string length limit #42218, which already conflicts with main in two other files.

Not deleted, because another pull request already has it or uses it:

Probably dead, left for a maintainer to decide:

  • Bun__signpost_emit and its #if OS(DARWIN) block in c-bindings.cpp: no Rust declaration and no caller. A comment in src/bun_core/util.rs says that the macOS signpost path is not wired yet.
  • myersDiff in src/js/internal/assert/myers_diff.ts and its native chain: nothing reads it since assert: render Myers diffs natively #39924. It mirrors Node's internal/assert/myers_diff, which a vendored Node test can load with --expose-internals.
  • AsyncContextFrame.exchange in src/js/internal/async_context_frame.ts: no caller. The file header says that it ports the Node surface.
  • Six unused definitions in src/runtime/ffi/FFI.h. A removal changes the text that viewSource() prints.
  • 36 of the 48 <Class>_getter functions that WEBCORE_GENERATED_CONSTRUCTOR_GETTER defines in ZigGlobalObject.cpp. A removal needs a second macro.

Self-review concerns that this PR does not take:

  • A one-time clang-tidy pass for unused declarations (three concerns). Left for a later sweep.
  • A checked-in sweep procedure with a script that lists what open pull requests already hold (two concerns). It is outside this PR.

Question for a maintainer: 57 dead-code sweep pull requests from this account are open, and none has merged since #43976 on 2026-09-26. Should the sweep continue to open standalone pull requests?


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

…torHTTPServerAgent.cpp, and JSBuffer.cpp

Delete five declarations that nothing references:

- ExceptionOr.h: the free function isolatedCopy(ExceptionOr<void>&&)
- Exception.h: the free function isolatedCopy(Exception&&), whose one
  caller was the function above
- ErrorCode.h: the alias ErrorCodeCache::Field
- InspectorHTTPServerAgent.cpp: the typedefs RouteId and RequestId
- JSBuffer.cpp: the member JSBuffer::typeRange
@robobun

robobun commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 9:09 AM PT - Oct 17th, 2026

✅ @robobun, your commit 34b42e02e6eb6f1ea24bccd8113868d1b3512424 passed in Build #127455! 🎉


🧪   To try this PR locally:

bunx bun-pr 45725

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

bun-45725 --bun

@robobun

robobun commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator Author

Status: ready for review.

How each deletion was verified:

  1. A name search on this branch finds no reference to the declaration. The exact commands are in the Notes block of the description.
  2. The debug build (bun bd) links, and the test files named in the description pass.
  3. On 2026-10-17 I fetched all open pull request heads over git and checked each one: none deletes one of these declarations, and none adds a use of a removed name. One open pull request gets a new conflicted file from this change (see Downsides).

This PR deletes code only. It has no test because no caller can observe a difference.

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: oven-sh/bun/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 951f7241-70bc-4f1e-beb6-bce373a4fe29
📥 Commits

Reviewing files that changed from the base of the PR and between 017b243 and 34b42e0.

📒 Files selected for processing: 5
  • src/jsc/bindings/ErrorCode.h
  • src/jsc/bindings/Exception.h
  • src/jsc/bindings/ExceptionOr.h
  • src/jsc/bindings/InspectorHTTPServerAgent.cpp
  • src/jsc/bindings/JSBuffer.cpp
💤 Files with no reviewable changes: 5
  • src/jsc/bindings/InspectorHTTPServerAgent.cpp
  • src/jsc/bindings/ErrorCode.h
  • src/jsc/bindings/JSBuffer.cpp
  • src/jsc/bindings/Exception.h
  • src/jsc/bindings/ExceptionOr.h

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

Walkthrough

This change removes exception-copy overloads and several type declarations and constants from JavaScriptCore bindings. The Exception constructor and Route::route_id field remain.

Changes

Binding declaration cleanup

Layer / File(s) Summary
Exception isolated-copy overloads
src/jsc/bindings/Exception.h, src/jsc/bindings/ExceptionOr.h
The namespace-level isolatedCopy(Exception&&) overload and the ExceptionOr<void> overload were removed. The Exception constructor remains.
Other binding declarations
src/jsc/bindings/ErrorCode.h, src/jsc/bindings/InspectorHTTPServerAgent.cpp, src/jsc/bindings/JSBuffer.cpp
The ErrorCodeCache::Field alias, RouteId and RequestId typedefs, and JSBuffer::typeRange constant were removed. Route::route_id remains declared as int.

Suggested reviewers: cirospaciari

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 34b42

No actionable behavior change or merge-blocking risk is established; this change is mergeable after normal checks.

Pre-merge checks: Passed 4
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly identifies the primary change: removing dead code from the listed binding files.
Description check Passed The description explains the changes, confirms no behavior change, documents verification steps and test results, and provides relevant background. It does not use the exact template headings, but it …
Full details: Description check

Explanation

The description explains the changes, confirms no behavior change, documents verification steps and test results, and provides relevant background. It does not use the exact template headings, but it includes the required information.

✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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

LGTM — five pure deletions of unreferenced declarations, each confirmed to have no consumer.

What was reviewed:

  • The deleted free isolatedCopy(Exception&&) / isolatedCopy(ExceptionOr<void>&&): every cross-thread copy of an Exception in the tree (the WebCrypto crossThreadCopy(WTF::move(result)) path and the CrossThreadCopierBase<..., ExceptionOr<T>> specializations in ExceptionOr.h) passes a const Exception&, which WTF routes to the member Exception::isolatedCopy() const that is kept; no unqualified rvalue call exists in src/ or packages/.
  • JSBuffer::typeRange: the local JSBuffer class is used only for JSBuffer::info()/s_info and is never a jsCast/inherits target; JSC reads type ranges from InheritsTraits<T> specializations, not a class member.
  • RouteId/RequestId typedefs: no remaining C++ use, the Route struct passed over the C ABI uses int route_id directly, so no ABI effect; ErrorCodeCache::Field has no references.
Extended reasoning...

The change is a single commit removing 21 lines across five files in src/jsc/bindings: two free rvalue isolatedCopy overloads, a type alias in ErrorCodeCache, two unused extern "C" typedefs, and a static constexpr member on a ClassInfo-only class. It touches no security-sensitive surface and no CODEOWNERS entry covers these paths. I confirmed by grep that each symbol has no caller, and traced the one non-obvious path (WTF crossThreadCopy on ExceptionOr results from the WebCrypto work queue) to the retained member isolatedCopy() rather than the deleted free functions. The bug hunt exited on dry_streak with no findings, and the deletions cannot change runtime behavior if they compile, which CI will confirm.

alii pushed a commit that referenced this pull request Oct 18, 2026
…ent.cpp (#45764)

### Problem
- 29 lines in 6 files have no user.
- `source_file`, `compare_types` and `symbol_to_string` in the
`queries!` list of `src/lint/types/mod.rs` have no caller. The list
generates the only call of the `Services` functions of the same names in
`bun_sema`. The trait is `pub`, so rustc does not check it.
- `BunProcess.cpp` declares five `using X = JSC::X;` aliases that it
never names. `DirEntType` in `NodeDirent.cpp` has three enumerators that
nothing names.

### Fix
- Delete the three list lines with their `Services` functions (21
lines), the five aliases and the three enumerators.
- Correct because a word search over the sources, the tests and the
generated code finds no user, and the workspace compiles for 12 targets.
- Verified: `bun bd`, `bun run rust:check-all`, `cargo check --workspace
--all-targets`, 8 test files (Notes).
- Self-reviewed: 41 concerns raised, 33 addressed. Rejected: a
`pub(crate)` narrowing of `Queries` (`resolve_name` needs a caller
first), and a hold until earlier sweeps merge.

### Background
- `queries!` lists each question that a lint handle (`Type`, `TsSymbol`)
can ask the type checker. One line generates a `Queries` method and a
forwarding call to `Services` in `bun_sema`.
- `BunProcess.cpp` compiles as its own unit with `using namespace JSC;`,
so the aliases change no name lookup.
- A deletion of unreferenced code has one possible place, so no other
design was weighed.

### Downsides
- A later lint handle that needs one of the three queries must restore
it.
- None found for users. Checked: the heads of all 5,559 open pull
requests, 12 targets, the tests in Notes.

Behaviour change: none
<details><summary>Notes</summary>

**Removed**
- `src/lint/types/mod.rs`: the `queries!` lines `source_file`,
`compare_types` and `symbol_to_string`. No call of these names has a
`Queries` receiver. The calls that exist go to other functions:
`Checker::compare_types` and `Checker::symbol_to_string` in `bun_sema`,
a private `compare_types` in `prefer_optional_chain.rs`, and the
parser's `source_file`. With `Queries` made crate-private in a scratch
edit, rustc reports `resolve_name` as the only query left that is never
used.
- `src/sema/check/services.rs`, `services/types.rs`,
`services/symbols.rs`: `Services::source_file`,
`Services::compare_types`, `Services::symbol_to_string`. The generated
forwarding call was the only user. What they call (`Files::by_path`,
`Checker::compare_types`, `Checker::symbol_to_string`,
`Checker::prop_to_string`) keeps other callers.
- `src/jsc/bindings/BunProcess.cpp`: the aliases `Exception`,
`JSModuleLoader`, `JSModuleRecord`, `SourceOrigin`, `JSNonFinalObject`.
None of the names appears in the rest of the file. The same block in
`Path.cpp` and `ZigGlobalObject.cpp` is left to #43378 and #42431.
- `src/jsc/bindings/NodeDirent.cpp`: the enumerators `Whiteout`, `Door`
and `EventPort` of `DirEntType`, all equal to `Unknown`. No C or C++
file names them.

**Open pull requests**
- Compared at 2026-10-17 16:40 UTC on main 017b243 with the heads of
all 5,559 open pull requests, drafts and every author included.
- 156 of them touch a file of this diff (151 touch `BunProcess.cpp`). A
trial merge of each with main and with this branch (`git merge-tree`)
shows that the branch adds a conflict to none.
- None deletes one of these lines. None adds a use of a removed name:
the added lines were searched for the three query names, the five alias
names in `BunProcess.cpp`, and the three enumerators.

**Found dead in this run, and left alone**
- Already gone on main: three lines in `JSSQLStatement.cpp` and
`NodeSqlite.cpp` (#45304).
- Another open pull request deletes or rewrites them: 13 commented-out
lines in uSockets, uWS, `JSEventTargetCustom.cpp` and
`src/node-fallbacks/url.js` (#45709, and #43730 for `url.js`), two
typedefs in `InspectorHTTPServerAgent.cpp` (#45725), the
`BUN_WEBKIT_VERSION` fallback in `BunProcess.cpp` (#41729), a
commented-out line in `src/js/internal/html.ts` (#45682).
- An open pull request uses them: `Event::currentTargetIsInShadowTree()`
and the `MediaTime` overload of `JSConverter<IDLUnrestrictedDouble>`
(#45415).
- Held by an earlier sweep for a reason that still holds: the QUIC
setters `scid_len` and `delay_onclose` (#43976, and #40220 changes the
line above them).
- `resolve_name`, the fourth query with no caller. tsgolint's
`prefer-readonly` calls `ResolveName` and Bun's port does not, which
gives a wrong autofix for a global enum. The fix is handed off and needs
the query. After it, `Queries` can become `pub(crate)`, and rustc then
guards the list.
- Mirrors of typescript-eslint and tsgolint: the write-only fields
`ThenCall::on_fulfilled`, `FinallyCall::on_finally`,
`BaseTypeOfClassMember::base_type` and `heritage_token`,
`TargetElement::is_shorthand`, with `TsNode::token` (as #45402 held
them). Also 33 functions from macro lists in `src/lint/types/` that
nothing calls, and `File::expr_tags_in_tree`.
- Debugging aids: 25 hand-written `Debug` impls in `bun_lint`, 5 in
`bun_format`, and `Display` for `Difference`, `FilePoll` and `Part`.
- Handed off: the plugin `target` value that nothing reads
(`BundlerPlugin::target`, three more members, a parameter of
`JSBundlerPlugin__create`, and the Rust enum). Its removal changes an
FFI signature.
- Needs a decision: `PerformanceResourceTiming` cannot be constructed,
so `ResourceTiming.cpp`, `NetworkLoadMetrics.cpp` and `ServerTiming.h`
are reachable only from its getters.

**How the candidates were found**
- Ten text searches, one for each area: `src/js`, the C++ bindings
(three parts), uSockets and uWS, the build scripts, the side packages,
the three new crates, and commented-out code.
- A relink of the debug build with `-Wl,--gc-sections`, with each
dropped function mapped to its source line by `llvm-nm -l`: 517 C++
functions and 607 Rust function lines. Almost all are Windows or macOS
code, release-only code, or are deleted by an open pull request.
- For `bun_sema`: `pub` narrowed to `pub(crate)` on each item that no
other crate names, in a scratch tree. rustc reported nothing new.
- For 39 trait impls that the linker drops: delete all, compile for
linux, windows and darwin and with `--all-targets`, put back each impl
that an error names. What stayed deleted is a debugging aid.

**Tests, debug build of this branch** (with `--timeout 600000`, because
the lint and check tests need more than the default with a debug build)
- `test/cli/lint/conformance.test.ts`: 3 pass.
- `test/cli/lint/rules.test.ts`: 16 pass.
- `test/cli/lint/native-rules.test.ts`: 166 pass.
- `test/cli/lint/bun-rules.test.ts`: 100 pass.
- `test/cli/check/check.test.ts`: 599 pass, 42 skip.
- `test/js/node/process/process.test.js`: 188 pass, 5 skip.
- `test/js/node/fs/dir.test.ts`: 23 pass.
- `test/regression/issue/24129.test.ts`: 2 pass.

</details>

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

---

**no test proof** · iteration 0 · 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 -->

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