Remove dead code from the bun_runtime re-export hubs, bun_core, bun_css, bun_install, bun_bundler, the FFI crates, and the error-code table

Merged
RO
3mo ago
+71-452

Rebase of #39319 (closed as stale) onto current main. Same content; the review on that PR was addressed there (the ServerInitContext report was a false positive, the comment nits are folded in), and per test/internal/source-lints/CLAUDE.md the dead-symbol lint test is not carried over. Net -400 lines in src/ (452 deleted, 52 added as reflowed import groups, visibility adjustments and comment updates), plus one inline-snapshot test in test/js/bun/test/snapshot-tests/bun-snapshots.test.ts that pins how ArrayBuffer values print (the one pretty_format match this PR edits). No behavior change.

Problem

bun_runtime re-export hubs (about 200 lines)

  • src/jsc/generated_classes_list.rs (116 lines), mounted as bun_runtime::GeneratedClassesList, was a flat alias namespace with no reader: generate-classes.ts resolves each .classes.ts class to its Rust type by walking the crate's own pub mod / pub use tree (rustModuleResolver, which only registers items at module depth 0, and everything in this file sat inside pub mod Classes { .. }), and the regenerated generated_classes.rs is byte-identical without the file. bun_runtime is also the only crate that can see its own re-export hubs (nothing but bun_bin depends on it, and bun_bin only calls Cli::start), so a hub entry rustc reports unused is unused everywhere.
  • api.rs still mirrored the old bun.api.* Zig namespace: 36 aliases (Image, Shell, Timer, Archive, Glob, HTMLRewriter, NativeZlib, Valkey, MySQL, Postgres, FFIObject, SocketHandlers, x509, the 18 process::* names other than Rusage, the five PTY types under bun::terminal, bun::H2FrameParser, posix_spawn, bun_spawn as spawn, ...) that no code and no generated code names. TCPSocket/TLSSocket stay: rustc reported them unused on linux, but socket/WindowsNamedPipeContext.rs imports them through api.
  • Same shape in bun.js.rs (pub use crate::{api, webcore}), webcore.rs (the five sink re-exports, form_data::{AsyncFormData, FormData}, and the webcore::jsc::codegen forwarding module whose own doc comment says it exists for call sites that "still spell" a path nothing spells), webcore/streams.rs (result::StreamResult), webcore/Request.rs (js_gen::from_js*), webcore/FormData.rs (get_boundary), s3/client.rs (multipart::{self}), bake/mod.rs (FrameworkRouter alias, DynamicRouteMap/EncodedPattern/Route/StaticRouteMap, production::{EntryPointMap, TypeAndFlags}), bake/dev_server/mod.rs (Assets, IncrementalGraph, RouteBundle, SourceMapStore), server/mod.rs (BunInfo, PreparedRequestFor, ServerInitContext, ServePluginsState), lib.rs (five cli::*_command crate-root aliases), cli/mod.rs (command::Command self-alias), cli/Arguments.rs (load_config), allocators/mod.rs, shell/interpreter.rs (Builtin), node/zlib/NativeZstd.rs (Context), api/JSBundler.rs (Config, MiniImportRecord), api/BunObject.rs (JSZstd::deallocator, whose own comment says "0 C++ refs, 0 Rust refs"), api/bun/Terminal.rs (from_js, from_js_direct) and api/bun/h2_frame_parser.rs (the CamelCase H2FrameParserConstructor twin of the snake_case alias the js2native thunk actually calls).
  • Seven items in server_body.rs, FrameworkRouter.rs and production.rs were reachable only through the deleted re-exports; they become pub(crate) (rustc's unreachable_pub demands it). ServerInitContext itself stays pub: it is still reachable through AnyRoute::from_js, and demoting it trips private_interfaces.

bun_runtime items (about 110 lines)

  • streams::Writable::{TemporaryAndDone, IntoArray, IntoArrayAndDone} are never produced (the StreamResult variants of the same names are; the Writable ones only had to_js arms). WritableFuture::Handler is never armed: the only construction is inside the run() arm that matches an existing Handler, so WritableHandler, WritableHandlerFn and that arm go with it.
  • Never-constructed variants and their match arms: DrainResult::Empty (webcore.rs, two matches! in Body.rs, one arm in ByteStream.rs), ReadableStream::Source::Direct (the C++ Tag::Direct maps to None in from_js; the FFI Tag enum itself is untouched), pretty_format::Tag::ArrayBuffer (JSType::ArrayBuffer maps to Tag::TypedArray; the now-unreachable _ => {} arm of print_as goes too), shell::IoKind::Stdin, node_fs_watcher::Event::Close (EventType::Close, which is used, stays), cron::CalendarError::OutOfMemory, thumbhash::DecodeError::OutOfMemory.
  • Trait items with no caller: ServerLike::{SSL_ENABLED, DEBUG_MODE, vm_mut} (RequestContext uses its own const generics; the inherent NewServer::vm_mut is still used and stays, and the two SAFETY comments that cited the trait item now cite it) and ResponseLike::upgrade with both impls (the HMR upgrade goes through the inherent uws methods).

Other crates (about 60 lines)

  • bun_core: the CodePointZero re-export in immutable.rs, and the ZERO_VALUE/MAX associated consts of CodePointZero (both impls; from_u32 is what the decoders use).
  • bun_css: css_parser::CustomMedia and IdentFns, the crate-root CustomIdentFns/DashedIdentFns, container::ContainerNameFns, selector::{_PrintErr, _Printer} ("re-export alias parity"), and the path re-export of the css_eql_partialeq! macro (every use is textual).
  • bun_install: PackageManager::{do_patch_commit, prepare_patch, GitResolver}, crate-root FolderResolution and PostinstallOptimizer, patch_install::PatchedDep.
  • bun_bundler: LinkerContext::{OutputFileListBuilder, StaticRouteVisitor, do_step5} module aliases, bundle_v2::{AdditionalFile, IndexStringMap}, options::BakeExtra. bun_collections::ArrayListAlignedIn and bun_sql_jsc::mysql::MySQLRequestQueue crate-level re-exports, bun_jsc::ZigErrorType crate-root re-export (the type is used by path).
  • FFI declarations with no caller on any target: windows_sys::kernel32::SetFileTime (its futimens caller was rewritten) and lsquic_sys::lsquic_conn_n_pending_streams.
  • ErrorCode.ts: 17 codes with no producer ($ERR_X( in src/js, ErrorCode::ERR_X in C++, ErrorCode::X in Rust, none in tests or docs; re-checked against today's main): ERR_BUFFER_CONTEXT_NOT_AVAILABLE, ERR_CRYPTO_INITIALIZATION_FAILED, ERR_CRYPTO_INVALID_COUNTER, ERR_CRYPTO_INVALID_TAG_LENGTH, ERR_CRYPTO_JOB_INIT_FAILED, ERR_CRYPTO_SCRYPT_INVALID_PARAMETER, ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, ERR_INVALID_ADDRESS, ERR_INVALID_PACKAGE_CONFIG, ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE, ERR_MISSING_PLATFORM_FOR_WORKER, ERR_NON_CONTEXT_AWARE_DISABLED, ERR_REQUIRE_ASYNC_MODULE, ERR_TLS_PSK_SET_IDENTITY_HINT_FAILED, ERR_WASI_NOT_STARTED, ERR_WORKER_INIT_FAILED, ERR_SECRETS_NOT_AVAILABLE. Everything that consumes the table is generated from it, so the renumbering is invisible.

Fix

  • Deletes the items above; the only other edits are the ones the deletions force (match arms, reflowed pub use groups, the seven pub -> pub(crate) changes, and the comments that named the removed items, including the VirtualMachine.rs LAYERING comments and the generate-classes.ts resolver comment that used removed api aliases as examples).
  • How the Rust candidates were found: the workspace builds with dead_code = deny, so the only dead Rust left is pub items, which rustc exempts. For every crate, pub was temporarily demoted to pub(crate) on the items no file outside the crate mentions (and, for bun_runtime, on everything the codegen output and bun_bin do not mention), and cargo check -p <crate> was run for x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc and aarch64-apple-darwin. An item was only deleted when rustc reported it unused on all three; items it reported on one target only (ipc.rs, node_fs.rs, cron.rs's Windows and macOS error variants, the api.rs socket aliases) and items only reached through macros expanded in other crates (bun_alloc's zone methods, bun_clap's const-eval helpers, js_class_module!'s IntoRawMut) were kept.
  • Verified on the rebased tree: bun bd (regenerates the class, js2native, host-export and error-code codegen and links; generated_classes.rs and generated_js2native.rs are byte-identical to main's, generated_host_exports.rs differs only in line-number comments), bun run rust:check-all, and bun bd test on the stream, body, fs.watch, shell and error-code test files listed in the first comment. Checked line by line against the two dead-code PRs still open (#37181, #37659): no shared deletions.

Left alone

  • strings::rsplit_once has no caller, but clippy.toml names it as the replacement for the disallowed str::rsplit_once / str::rsplitn / ByteSlice::rsplit_once_str, so it is kept (it was deleted in the first push of this PR and restored after review).
  • Still on main and unclaimed now that the PRs that used to cover them were closed as stale, so candidates for the next sweep rather than this rebase: webcore.rs's DOMExceptionCode re-export, install/lib.rs's TextLockfile, ffi/mod.rs's ffi_object_draft, streams.rs's never-produced StreamResult variants, the image/mod.rs / dns_jsc/mod.rs / node_fs.rs re-export groups, Blob.rs's structured-clone helpers, server/mod.rs's ref_, shell_body.rs's InvalidArguments/Todo, bindgen.rs's three marker structs, and the ERR_REDIS_* / ERR_KEY_GENERATION_JOB_FAILED codes.
  • Deliberately kept although rustc reports them: napi_status variants, SSRKind::Regular, serialized_failure::ErrorKind's JS variants and MessageId::Visualizer (external code tables), bake::Mode::ProductionDynamic (a documented mode placeholder), ERR_POSTGRES_INVALID_BYTE_SEQUENCE_FOR_ENCODING (documented in docs/runtime/sql.mdx), and the unused entries of the O::, EPOLL::, IN:: and POLL_* constant tables in bun_sys.

[review] gate passed · iteration 2 · 60 files touched

fails on main (without fix)
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/js/bun/test/snapshot-tests/bun-snapshots.test.ts
ninja: Entering directory `/workspace/bun/build/debug'
[1/182] gen ErrorCode+*.h
[2/182] gen bake.{client,server,error}.js
-> bake.client.js, bake.server.js, bake.error.js
[3/182] gen JSBuffer.lut.h
Generating /workspace/bun/build/debug/codegen/JSBuffer.lut.h from /workspace/bun/src/jsc/bindings/JSBuffer.cpp
[4/182] gen generated_host_exports.rs
generated_host_exports.rs: 92 exports (host=3, lazy=10, generic=79, rust=0); 241 extern-C blocks audited
[5/182] 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/
... (truncated)

release without fix: all passed
bun test v1.4.0-canary.1 (549023443)

test/js/bun/test/snapshot-tests/bun-snapshots.test.ts:
(pass) it will create a snapshot file if it doesn't exist [0.33ms]
(pass) ArrayBuffer values are serialized like typed arrays [0.06ms]
(pass) toMatchSnapshot errors > should throw if property matchers exist and received is not an object [0.05ms]
(pass) toMatchSnapshot errors > should throw if property matchers don't match [0.11ms]
(pass) toMatchSnapshot errors > should throw if arguments are in the wrong order [0.04ms]
(pass) toMatchSnapshot errors > should throw if expect.any() doesn't received a constructor [0.06ms]

 6 pass
 0 fail
 10 snapshots, 28 expect() calls
Ran 6 tests across 1 file. [171.00ms]
__F:0:S:0
passes on PR (with fix)
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/js/bun/test/snapshot-tests/bun-snapshots.test.ts
bun test v1.4.0 (8326d1bd3)

test/js/bun/test/snapshot-tests/bun-snapshots.test.ts:
(pass) it will create a snapshot file if it doesn't exist [34.63ms]
(pass) ArrayBuffer values are serialized like typed arrays [4.57ms]
(pass) toMatchSnapshot errors > should throw if property matchers exist and received is not an object [3.76ms]
(pass) toMatchSnapshot errors > should throw if property matchers don't match [12.92ms]
(pass) toMatchSnapshot errors > should throw if arguments are in the wrong order [5.64ms]
(pass) toMatchSnapshot errors > should throw if expect.any() doesn't received a constructor [7.16ms]

 6 pass
 0 fail
 10 snapshots, 28 expect() calls
Ran 6 tests across 1 file. [2.71s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 823ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/142] gen ErrorCode+*.h
[2/142] gen bake.{client,server,error}.js
-> bake.client.js, bake.server.js, bake.error.js
[3/142] gen JSBuffer.lut.h
Generating /workspace/bun/build/release/codegen/JSBuffer.lut.h from /workspace/bun/src/jsc/bindings/JSBuffer.cpp
[4/142] gen generated_host_exports.rs
generated_host_exports.rs: 92 exports (host=3, lazy=10, generic=79, rust=0); 241 extern-C blocks audited
[5/142] 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)
  - 
... (truncated)
diff hotspot
src/bun.js.rs                                      |   4 -
 src/bun_core/Global.rs                             |   2 +-
 src/bun_core/string/immutable.rs                   |   1 -
 src/bun_core/string/immutable/unicode.rs           |   9 +-
 src/bundler/LinkerContext.rs                       |   3 -
 src/bundler/bundle_v2.rs                           |   4 +-
 src/bundler/lib.rs                                 |   1 -
 src/codegen/generate-classes.ts                    |   4 +-
 src/collections/lib.rs                             |   1 -
 src/css/css_parser.rs                              |   3 +-
 src/css/generics.rs                                |   1 -
 src/css/lib.rs                                     |   2 +-
 src/css/rules/container.rs                         |   1 -
 src/css/selectors/selector.rs                      |   3 -
 src/install/PackageManager.rs                      |   4 +-
 src/install/lib.rs                                 |   2 -
 src/install/patch_install.rs                       |   2 -
 src/jsc/VirtualMachine.rs                          |   6 +-
 src/jsc/bindings/ErrorCode.ts                      |  17 ---
 src/jsc/generated.rs                               |   7 +-
 src/jsc/generated_classes_list.rs                  | 116 ---------------------
 src/jsc/lib.rs                                     |  11 +-
 src/lsquic_sys/lib.rs                              |   1 -
 src/runtime/allocators/mod.rs                      |   2 -
 src/runtime/api.rs                                 |  53 +---------
 src/runtime/api/BunObject.rs                       |   3 -
 src/runtime/api/JSBundler.rs                       |   6 +-
 src/runtime/api/bun/Terminal.rs                    |   4 +-
 src/runtime/api/bun/h2_frame_parser.rs             |   1 -
 src/runtime/api/cron.rs                            |   7 +-
 src/runtime/bake/DevServer.rs                      |  18 ----
 src/runtime/bake/FrameworkRouter.rs                |  10 +-
 src/runtime/bake
... (truncated)

gate history · 3 passed · 2 rejected · iteration 2

evidence per changed file
file                                      reads  edits  tests
src/bun.js.rs                                 1      1      0
src/bun_core/Global.rs                        0      0      0
src/bun_core/string/immutable.rs              0      0      0
src/bun_core/string/immutable/unicode.rs      0      0      0
src/bundler/LinkerContext.rs                  0      0      0
src/bundler/bundle_v2.rs                      0      0      0
src/bundler/lib.rs                            0      0      0
src/codegen/generate-classes.ts               1      0      0
src/collections/lib.rs                        0      0      0
src/css/css_parser.rs                         0      0      0
src/css/generics.rs                           0      0      0
src/css/lib.rs                                0      0      0
src/css/rules/container.rs                    0      0      0
src/css/selectors/selector.rs                 0      0      0
src/install/PackageManager.rs                 0      0      0
src/install/lib.rs                            0      0      0
(+ 44 more files)