Remove dead code from bun_core, bun_css, bun_jsc, and the FFI crates

Closed
RO
3mo ago
+183-675

Net -631 lines of Rust source (49 files), plus a 139-line source lint that keeps the symbols from coming back.

Method: ran the repo's hawk setup (tools/hawk/, dead_public only) once per target for linux-gnu, linux-musl, android, freebsd, darwin and windows-msvc, and kept only the items reported unreachable on every target (test targets included). Items whose file is touched by one of the currently open dead-code PRs were dropped if that PR removes the same symbol (checked against each PR's diff), so nothing here duplicates an open PR. Every remaining item was then re-checked by hand with rg over src/, src/codegen/ and freshly regenerated build/debug/codegen/ before deletion; that pass caught a few hawk false positives, listed at the bottom.

bun_css (-203)

The inherent eql / to_css / parse forwarders that predate the CssEql / ToCss / Parse trait impls; every caller already goes through the traits.

  • Calc::eql, MathFunction::eql and the private eql_calc_list they shared (values/calc.rs)
  • CalcValue::eql trait hook and its six impls: its only caller was Calc::eql. That in turn made the UFCS-only inherent Time::eql and Angle::eql dead (Angle::eql is pub(crate), so rustc flagged it once the trait hook was gone); both removed
  • Token::eql, Num::eql, Dimension::eql (css_parser.rs) and generics::implement_eql, which only they called
  • generics::parse<T: Parse> free function
  • DefaultAtRule::to_css (whole impl block)
  • GenericSelectorList::to_css, GenericSelector::to_css, GenericComponent::to_css, Combinator::to_css: #[deprecated] tombstones that unconditionally unreachable!()
  • TokenList::parse_with_options, CssStringFns::parse (and the css::CssResult as Result import only it used)

bun_jsc (-175)

  • BuiltinName::get and the private BUILTIN_NAME_MAP comptime map that only it read (lib.rs)
  • MarkedArrayBuffer::to_js (every holder goes through to_node_buffer / destroy)
  • TopExceptionScope::new, ExceptionValidationScope::new (all construction goes through init / init_guard*)
  • JSGlobalObject::to_js, JSGlobalObject::ref_, JSGlobalObject::ctx (the latter two were already marked for deletion in a comment)
  • AbortReason::to_js (whole impl block, plus the CommonAbortReasonExt import only it used), JSCell::to_js, JSValue::cast, ErrorBuilder::new (values are built with a struct literal), TagPayload::get, task::new, JsPtr::on_js_thread, Completion::off_thread, UUID::ZERO

bun_core, bun_alloc, bun_ast, bun_ptr (-134)

  • bun_core: RawSlice::from_raw, the buffer concat in lib.rs (callers use strings::concat), SliceWithUnderlyingString::from_utf8, BoundedArrayAligned::get, ExternalShared::as_ptr, ExternalSharedOptional::get, Unaligned::new, Mutex::get_mut, RwLock::get_mut, GenericIndexOptional::{is_some, is_none, get}, Timespec::new, and the write::Result alias (bun_io defines its own)
  • bun_alloc: impl AllocError { name } (wrapping error types hardcode the string), the top-level usable_size (the default_alloc::usable_size everyone calls stays), BSSList::init (bss_singleton! uses init_at)
  • bun_ast: symbol::Map::init
  • bun_ptr: BackRef::shared, DetachablePtr::as_ptr

sys crates (-119)

  • bun_sys: both cfg variants of UTIME_OMIT and its c:: re-export, the raw posix::read wrapper, DynLib::handle
  • bun_uws_sys: NewSocketHandler::group and AnySocket::group, the SocketTcp / SocketTls type aliases and their re-exports (the same-named AnySocket variants are what everything uses), AnyResponse::init, SocketGroup::is_empty, PosixLoop::wake, PosixLoop::run, Opcode::Close (the Opcode::Close in bun_http is a different type), and the non-Windows WindowsLoop stub alias (its only users are #[cfg(windows)])
  • bun_windows_sys: the WaitForSingleObject Result wrapper and its raw extern (bun_sys and the install shim each declare their own; the shim's dead re-export of it is dropped too), NTSTATUS::raw
  • bun_boringssl_sys: GeneralNames::is_empty, X509_V_OK, SSL_SESS_CACHE_CLIENT
  • bun_cares_sys: impl AddrInfo_hints { is_empty }
  • bun_zlib_sys: the z_alloc_fn / z_free_fn legacy aliases and their re-export, Byte
  • bun_tcc_sys: SymbolCallback alias and its re-export

Comment lines that named a removed item were trimmed; no comments were added.

Verification

  • cargo check --workspace on all ten CI triples (bun run rust:check-all), plus --cfg bun_debug --cfg bun_asan and --cfg bun_codegen_embed --all-targets on linux: clean, so no dead_code / unused_imports fallout is left behind
  • cargo fmt --check clean; full bun bd builds
  • bun bd test on test/js/bun/css/{css,color}.test.ts, test/bundler/css/css-modules.test.ts, test/js/web/abort/abort.test.ts, test/js/bun/util/inspect.test.js, test/js/node/zlib/deflate-streaming.test.ts, test/js/bun/net/localhost-loopback-contract.test.ts: all pass
  • test/internal/source-lints/dead-symbols-cross-crate-sweep.test.ts: every one of its 67 entries fires against the pre-PR sources and none fire after

Found dead but deliberately left alone

  • CssModuleReference::eql: dead on main, but #36225 (handle_composes) starts calling it, so it stays
  • StoredTrace::from: only caller is under #[cfg(bun_debug)] (hawk ran without that cfg); live
  • host_fn::host_fn_this_value: generate-classes.ts can still emit calls to it
  • strings::{split_once, rsplit_once, rsplit_once_char}: no callers, but clippy.toml points people at them as the sanctioned replacements for the std versions; removing them means rewording those entries
  • hawk reports constants used only in const-generic / array-length / const _: assertion positions as dead (Kind::ABS/REL, PROPERTY_BITSET_BITS, CALLBACK_COUNT, DeferredRequest::MAX_PREALLOCATED, native_promise_context::Tag::COUNT, MAX_CID_LEN, ARES_EDESTRUCTION as an enum discriminant); all live, all kept. Its module findings are also not "module unused" (ffi::ffi, udp::raw, bake::jsc are all used), so none were acted on
  • Single unused entries of otherwise-complete flag/code tables (O::{NOATIME, DSYNC, SYMLINK, NOFOLLOW_ANY}, posix::R_OK, posix::POLL_OUT, TCSA / RlimitResource variants) were left for table completeness, matching the overrides already in hawk.toml
  • ~300 never-read pub fields and ~25 never-constructed variants are reported on every target as well; those need per-field judgment (repr(C) layouts, liveness anchors, generated accessors) and are left for a separate pass
  • The rest of the all-target findings (~730 lines, mostly simdutf/lsquic/uws/zlib/windows_sys bindings and a few runtime items) are already deleted by the open dead-code PRs #38439, #38213, #37181, #37332, #38005, #37149, #37062, #36237, #37012, #36115 and #37272, so they are intentionally not repeated here