Repository navigation
Conversation
…er crates
Delete code that nothing reaches. The workspace denies dead_code, but
these items are pub, trait impls, write-only fields, or branches behind
an option that no caller sets.
bun_css: the CSS-modules export and reference tables, Config.dashed_idents,
DashedIdentReference.from, Pattern::write_to_string*, Segment::Name, the
analyze_dependencies printer option with Dependency, ImportDependency,
UrlDependency, DependencyOptions, Printer.{dependencies,remove_imports},
Printer::get_import_records, Url::is_absolute, and
PrinterErrorKind::ambiguous_url_in_custom_property.
bun_react_compiler: the logger event types (LoggerEvent, OrderedLogItem,
DebugLogEntry, CompilerErrorDetailInfo, LoggerSuggestionInfo,
LoggerSuggestionOp, CompilerErrorItemInfo, LoggerSourceLocation,
LoggerPosition), the events, ordered_log and renames fields of
CompileOutput with their producers, count_memo_blocks, the
logged_severity methods, and never-constructed enum variants.
Smaller crates: RefCounted::debug_name and its macro key, HasLength impls
for [u8], &str and &String, the unused tcc Error and OutputFormat
variants, the unused to_*_error_instance helpers in bun_jsc,
WeakRefType::PostgreSQLQueryClient, five RedisError variants with their
four ERR_REDIS_INVALID_* codes, IntoOptionalData for &mut Data, the
notImplementedIssue codegen rule, and 54 stale declarations in
src/js/builtins.d.ts.
Add a source lint that pins the module-level #![allow(dead_code)] and
dead-code analysis is a deliberate change.
Contributor
|
Warning Review limit reached
On-demand reviews are free for the next 24 days. After that, they cost $0.25 per reviewed file. Or wait 10 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 selected for processing (49)
Comment |
Collaborator
Author
|
Status: ready for review. The diff is green; CI is red only on lanes this PR does not touch.
|
Collaborator
Author
|
Updated 10:18 PM PT - Aug 27th, 2026
❌ @robobun, your commit 6d7ad04 has 1 failures in
🧪 To try this PR locally: bunx bun-pr 40690That installs a local version of the PR into your bun-40690 --bun |
This was referenced Aug 28, 2026
Open
This was referenced Sep 14, 2026
Jarred-Sumner
pushed a commit
that referenced
this pull request
Sep 21, 2026
### Problem - 49 hand-written trait impls across 12 crates have no user: no call, and no bound that needs them. - rustc's `dead_code` lint exempts trait impls, so the workspace's deny lints never report them. ### Fix - Delete the 49 impls and `hash_array_list` (`src/css/generics.rs`), whose only caller was a removed impl. 25 files, 436 lines removed. - Candidates come from the linker: in a relink of the debug build with `--gc-sections`, an impl block with no kept function address is a candidate. The compiler decides next: an impl that a bound, a supertrait, another target, or a unit test needs does not compile away, so it stays. That kept 128 of 233 candidates. - 56 more stayed by choice: open PRs use them, docs describe them, or they are std ergonomics impls on shared containers. See the Notes. - Verified: `bun run rust:check-all` (12 targets), `cargo check --release` (3 targets), `cargo check --tests`, `cargo clippy`, `bun bd`, 11 test files, and a scan of all open PRs for users. ### Background - To rustc a trait impl is always reachable: generic code could call it. Only a whole-program view shows that nothing does. - The debug build uses opt-level 0 and one section per function, so `--gc-sections` drops every function with no caller. Callers in generic instantiations and macro-expanded code count. - That link proves linux only. `cargo check` covers the other targets. - #39795 removed 92 impls this way. <details><summary>Notes</summary> **Removed impls, by file** - `src/ast/e.rs` - `impl From<f64> for Number` - `src/bun_alloc/baby_vec.rs` - `impl<'a, 'b, T: Copy> Extend<&'b T> for BabyVec<'a, T>` - `impl<'a, 'b, T> IntoIterator for &'b BabyVec<'a, T>` - `impl<'a, 'b, T> IntoIterator for &'b mut BabyVec<'a, T>` - `impl<'a, T> core::borrow::Borrow<[T]> for BabyVec<'a, T>` - `impl<'a, T> AsRef<[T]> for BabyVec<'a, T>` - `src/bun_alloc/lib.rs` - `impl<const N: usize> BSSAppendable for [&[u8]; N]` - `src/bun_core/atomic_cell.rs` - `unsafe impl<U> Atom for *const U` - `src/bun_core/fmt.rs` - `impl From<InvalidCharacter> for crate::CrateError` - `src/bun_core/output.rs` - `impl<T: fmt::Display> FmtTuple for &[T]` - `src/bundler/Chunk.rs` - `impl core::ops::Index<usize> for CompileResultSlots` - `src/bundler/bundle_v2.rs` - `impl Ord for StableRef` - `impl PartialOrd for StableRef` - `src/collections/array_hash_map.rs` - `impl<K, V, C, A: MapAllocator> ArrayHashMapExt for ArrayHashMap<K, V, C, A>` - `src/css/generics.rs` - `impl<'bump, T: DeepClone<'bump>> DeepClone<'bump> for &'bump T` - `impl<T: CssEql, const N: usize> CssEql for [T; N]` - `impl CssHash for ()` - `impl<T: CssHash, const N: usize> CssHash for [T; N]` - `impl<'bump, T: CssHash> CssHash for ArrayList<'bump, T>` - `impl CssHash for bun_ast::Loc` - `impl<T: IsCompatible, const N: usize> IsCompatible for [T; N]` - `impl<'bump, T: ToCss> ToCss for ArrayList<'bump, T>` - `impl ToCss for CustomIdent` - `impl ToCss for DashedIdent` - `impl ToCss for Ident` - `src/css/media_query.rs` - `impl crate::generic::ToCss for MediaList` - `src/css/properties/mod.rs` - `impl crate::generics::ParseWithOptions for css_values::length::Length` - `impl<S, const P: u8> crate::generics::Parse for GenericBorder<S, P>` - `src/css/rules/supports.rs` - `impl crate::generics::CssEql for SupportsCondition` - `impl css::generic::ToCss for SupportsCondition` - `src/css/selectors/parser.rs` - `impl<Impl: SelectorImpl> Default for GenericSelector<Impl>` - `impl<Impl: BunSelectorImpl> CssEql for GenericSelectorList<Impl>` - `impl<Impl: BunSelectorImpl> CssHash for GenericSelectorList<Impl>` - `impl<Impl: BunSelectorImpl> CssEql for GenericComponent<Impl>` - `impl<Impl: BunSelectorImpl> CssHash for GenericComponent<Impl>` - `src/css/values/alpha.rs` - `impl crate::generics::CssHash for AlphaValue` - `src/install/lockfile/lockfile_json_stringify_for_debugging.rs` - `impl<const N: usize> JsonScalar for &[u8; N]` - `src/install/resolution.rs` - `impl Default for Tag` - `src/install_types/resolver_hooks.rs` - `impl<I: VersionInt> Default for ResolutionValue<I>` - `impl Default for Resolution` - `src/jsc/JSPropertyIterator.rs` - `impl IntoIterObject for *const JSObject` - `src/jsc/JSValue.rs` - `impl FromAny for ()` - `impl FromAny for &str` - `impl<T: FromAny> FromAny for Option<T>` - `src/jsc/host_fn.rs` - `impl<T> IntoHostConstructReturn for *mut T` - `src/react_compiler/hir/mod.rs` - `impl From<FloatValue> for f64` - `src/runtime/bake/DevServer.rs` - `impl From<OpaqueFileId> for OpaqueFileIdOrOptional` - `src/runtime/error.rs` - `impl From<Error> for bun_jsc::CrateError` - `src/tcc_sys/tcc.rs` - `impl<ErrCtx> Default for Config<ErrCtx>` **Candidates that stayed (184 of 233)** - 128: the workspace does not compile without the impl (a bound, a supertrait, another target, or a unit test needs it). - 8: open PRs use them. The six `SmallList` impls (`Deref`, `DerefMut`, `IntoIterator` x2, `FromIterator`, `Extend`) for #39497, #38692 and #36605. `Default for Wyhash` for #40372. `AsRef<[u8]> for Utf8Bytes` for #40708. This branch merged with #39497, #38692 and #40708 passes `cargo check --workspace`. #36605 and #40372 conflict with main on their own. - 19: std ergonomics impls on widely shared types. This is a design call, so it needs a maintainer decision and its own PR: `Interned` (`Deref`, `AsRef<[u8]>`, `Borrow<[u8]>`), `ZStr` (`AsRef<ZStr>`, `PartialEq<[u8]>`, `PartialEq<&[u8; N]>`), `StoreStr` (`PartialEq<[u8]>`), `StoreSlice` (`AsRef<[T]>`, `From<&[T]>`, `From<ArenaVec>`), `IntoIterator for &HashMap` and `&mut HashMap`, `BoundedArrayAligned` (`Deref`, `DerefMut`, `fmt::Write`), `AsRef<[T]> for RawSlice`, `Deref for ArenaString` (also the only caller of `ArenaString::as_str`), `Display for GenericIndex`, `Display for CowSliceZ`. - 21: docs or comments describe the impl as part of a design. `ArrayHashContext<Box<[u8], A>> for BoxedSliceContext<C>` (its doc comment records it as the fix for lookups reached through `Deref`), `Default for Ordinal` (the default is `INVALID`, not 0), `IntoLogWrite for &mut W`, `ThrowFmtArgs for fmt::Arguments`, `PoolStorage for UnwiredStorage`, `StringBuilder for semver_string::Builder`, `fmt::Write for FmtAdapter`, `AsFd for &File`, and the css blanket impls that the `css_derive` module docs and the `Parse` section of `src/css/generics.rs` name (`Option<T>`, `SmallList`, `bool`, `str`, `[u8]`, `[T]`, `Size2D`, `Rect`). - 6: next to a hunk of an open dead-code PR (#40690, #41335, #43010, #42278), left alone to avoid a conflict. - 2: the removal leaves something else half-used. See the follow-up list. **Method details** - Link: the debug link command from `build.ninja` plus `-Wl,--gc-sections`. `-rdynamic`, `--dynamic-list` and the version script stay, so the exported NAPI/V8/uv surface is still a root. - Liveness: `llvm-nm` lists the 669,524 kept function symbols and `llvm-symbolizer` maps each address to `file:line`. An impl block is a candidate when no kept address falls inside it and a rust-analyzer SCIP index shows that linux compiles every method in it. - Limit of the finder: it reads impl blocks from source text. Impls that a `macro_rules!` type list generates are not candidates, so unused arms of such lists are not in this PR. - Restore loop: delete all candidates, run `cargo check --workspace --keep-going --message-format=json`, put back each impl that an error names, repeat until clean. Targets in the loop: linux-gnu, windows-msvc, darwin, freebsd, android, musl, then `--tests`. - Method resolution: on linux the link proves that no call to a removed impl remains, so no call can resolve differently. On other targets a call that used a removed impl fails to compile. - Open PRs: main has no merge queue, so a green PR that uses a removed impl would break main when it merges. I fetched the heads of all 5474 open non-draft PRs, took the Rust lines each one adds against its merge base, and searched them for the types and traits of the 49 impls. No PR uses one. - Base: main at 18fe86e. The liveness data is from cf71211. The commits between them do not touch the 25 files, and every check above ran again on 18fe86e. - `cargo check --workspace --tests` reports one error, `src/bundler/options.rs:2328` (`expected ContentHash, found integer`). Clean main has the same error. This PR does not touch it. - Three tests fail in the local debug build with and without this change: `ffi.test.js` "FTL-compiled call site" (5 s timeout under ASAN), and two `serve.test.ts` tests that depend on the container (root can bind low ports, loopback check). **Other scans in this run** - Free functions, inherent methods, types, consts and statics: a name scan, the linker scan, and a rust-analyzer zero-reference scan for linux, windows and darwin. Every hit was platform code with a caller on another target, test-only code, or a deletion that an open PR already carries. - Also clean or already claimed: `.rs` files outside every mod tree, unused Cargo dependencies, extern declarations without a Rust caller, commented-out code in C++/TS, unused `src/js` modules and internal exports, linker-dropped C++ functions in `src/jsc/bindings`. **Follow-up candidates, not in this diff** - 25 hand-written `Debug` impls that nothing formats. They are a debugging aid, so this PR keeps them. - `Clone for JsPoster` has no caller, and it is the only reader of the `JsPosterVTable::clone` slot. Removing both is a small refactor in `src/event_loop` and `src/jsc/VmHandle.rs`. - `Display for ErrorLocation` (`src/css/error.rs`) has no caller, and it is the only reader of `ErrorLocation::filename`. - The 19 std ergonomics impls above, if a maintainer wants shared containers to go through inherent methods only. - `Bun__napi_get_version` in `src/jsc/bindings/napi.cpp` has no caller. - The class generator emits `<Type>Class__call` shims for classes that set `call: true` and `noConstructor: true` (the seven `Expect*` matchers in `jest.classes.ts`). Nothing references those shims. </details>
This was referenced Oct 17, 2026
Open
This was referenced Oct 27, 2026
This was referenced Nov 4, 2026
robobun
added a commit
that referenced
this pull request
Nov 7, 2026
…h.json input Nine rows of the private-name list were the property names of the node:path binding: basename, extname, format, isAbsolute, join, normalize, parse, relative and toNamespacedPath. #45631 removed the last read of each. No built-in spells $name for any of them. No native code reads namePublicName or namePrivateName. The generated code and the engine sources do not name them as private names. .vscode/launch.json: the input commandLine. Every configuration reads ${input:testName}, and nothing reads ${input:commandLine}. builtins.d.ts still declares a $name for each of the nine rows. #40690 and #37305 delete those lines, so this commit leaves them.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
bun_css,bun_react_compiler, and a few smaller crates.dead_code = "deny"cannot see it: the items arepub, or trait impls, or fields that are written but never read, or branches behind an option that no caller ever sets.PrinterOptions.analyze_dependencies, and the CSS-modules export and reference tables) and the React Compiler logger event types that no code constructs.Fix
rg -woversrc/,packages/,scripts/,test/,build/debug/codegen/), and the workspace compiles with the items gone. The full list is in the Notes below.bun_css(-820):analyze_dependenciesand theDependencytypes, theCssModuleexport and reference tables,Config.dashed_identsand thefromclause ofDashedIdentReference,Segment::Name.bun_react_compiler(-385): the logger event types, theevents,ordered_logandrenamesoutputs,count_memo_blocks, never-constructed enum variants. Smaller crates (-266):RefCounted::debug_name, unusedHasLengthimpls, tcc enum variants,bun_jscerror helpers,WeakRefType::PostgreSQLQueryClient, fiveRedisErrorvariants, stalebuiltins.d.tsdeclarations.test/internal/source-lints/module-lint-escapes.test.ts: it pins the module-level#![allow(dead_code)]and#![allow(unreachable_pub)]escapes per file, like the item-leveldead-code-escapes.test.ts. This change drops the escape inreact_compiler/compile_result.rs, so the lint fails onmainand passes here.bun bd,cargo check --workspace,bun run rust:check-all(12 targets),bun bd testontest/bundler/css,test/js/bun/css,test/bundler/transpiler/react-compiler-fixtures.test.ts,test/js/valkey,test/js/sql/local-sql.test.ts,test/js/sql/postgres-binary-numeric.test.ts,test/js/bun/ffi,test/js/bun/test/mock-fn.test.js,test/js/web/fetch/fetch.test.ts(same failures as a release build in this container), andtest/internal/source-lints.Background
bun_cssis a port of lightningcss. Bun renames CSS-module classes through the bundler symbol table, so the lightningcss export table was filled in and then dropped.analyze_dependenciesreplacesurl()and@importwith placeholders for a later rewrite pass. Bun resolves imports throughImportRecords instead, so the option was never set.WeakRefTypeis the tag Bun passes to JSC weak handles so C++ knows which Rust finalizer to call. ThePostgreSQLQueryClientarm declared a finalizer that was never defined.Notes
Removed, per crate:
bun_css: theexports_by_source_indexandreferencesmaps ofCssModule(written, never read) withget_reference,reference_dashed,add_dashed,add_local,CssModuleExports,CssModuleReferences,CssModuleExport,CssModuleReference;Config.dashed_idents(alwaysfalse);DashedIdentReference.fromandparse_with_options(alwaysNone);Pattern::write_to_string,Pattern::write_to_string_with_prefix,Segment::Name; theanalyze_dependenciesprinter option withDependency,ImportDependency,UrlDependency,DependencyOptions,Printer.{dependencies,remove_imports},Printer::get_import_records,Printer::replace_dots,Url::is_absolute,PrinterErrorKind::ambiguous_url_in_custom_property; theis_declarationparameter ofPrinter::write_dashed_ident; the raw-pointerreferencessetup inStyleSheet::to_css_with_writer_impl; three no-op#[cfg_attr(any(), derive(...))]attributes.bun_react_compiler:LoggerEvent,OrderedLogItem,DebugLogEntry,CompilerErrorDetailInfo,LoggerSuggestionInfo,LoggerSuggestionOp,CompilerErrorItemInfo,LoggerSourceLocation,LoggerPosition,BindingRenameInfo; theevents,ordered_logandrenamesfields ofCompileOutputwith their producers (convert_renames,BindingRename,Environment.renames,ProgramContext.renames);count_memo_blockswithCountMemoBlockVisitorand theDebugimpl forCodegenFunctionthat was its only reader; the fourlogged_severitymethods;Display for ReactiveTerminalTargetKind;Error for CompilerError;ErrorCategory::{Suppression, FBT},CompilerSuggestionOperation::{InsertBefore, InsertAfter, Remove},JsxImportKind::CreateElement,ValueReason::StoreLocal;ExactSizeIterator,PartialEq,EqandFrom<[K; N]>impls incollections.rs; the module-level#![allow(unreachable_pub)]incompile_result.rs.bun_ptr,bun_core_macros:RefCounted::debug_name,ThreadSafeRefCounted::debug_name,type_base_name, and thedebug_namekey of#[ref_count(...)](four attribute sites updated).bun_core:HasLengthimpls for[u8],&str,&String.bun_tcc_sys:Error::{SyntaxError, ExecError, OutputError},OutputFormat::{Exe, Dll, Obj, Preprocess}and the matchingTCC_OUTPUT_*constants.bun_jsc:to_type_error_instanceandto_range_error_instanceonEncodedSliceJsc,to_syntax_error_instanceandto_range_error_instanceonStringJsc(thesrc/CLAUDE.mdline that lists them is updated),WeakRefType::PostgreSQLQueryClientinWeak.rsandWeak.cpp.bun_valkey,bun_runtime:RedisError::{InvalidArgument, InvalidArray, InvalidBigNumber, InvalidErrorString, InvalidSimpleString}and theERR_REDIS_INVALID_{ARGUMENT, ARRAY, ERROR_STRING, SIMPLE_STRING}rows inErrorCode.ts.bun_sql_jsc:IntoOptionalData for &mut Data.notImplementedIssuerule insrc/codegen/replacements.ts(only theFnform is used), 54 staledeclarelines insrc/js/builtins.d.ts.Items the sweep saw and left alone, with the reason:
JSCrossRealmTransformState,CrossRealmTransform.cppand theCrossRealmstream enum arms (about 176 lines): unreachable, but the header states they are kept on purpose for transferable streams, andDOMIsoSubspaces.his included by every binding.macro(mockedFunction)andmacro(writer)inBunBuiltinNames.h(2 lines): unused, but the header is included by every C++ file.Connectionoutbound encoder insrc/runtime/api/bun/h2/(about 250 lines, test-only): part of a planned engine rewrite thath2/mod.rsdocuments.enableEmitHookGuards,validateBlocklistedImports,customHooks,moduleTypeProvider, and the write-onlyEnvironmentConfigfields, about 280 lines): un-wired upstream features rather than dead code.MinifyOptions.unused_symbols,ParserOptions.error_recovery,PrinterOptions.pseudo_classes,PrinterOptions.project_root,ParserFlags::{CUSTOM_MEDIA, NESTING},Targets.includeinbun_css(about 125 lines): always default today, but they are real lightningcss features and the files are touched by open PRs Remove dead code from bun_core, bun_jsc, bun_css, react_compiler, and two C++ bindings #40367 and Remove dead code from the js lexer, bun_runtime, bun_alloc, and 20 other crates #40610.prefixes::Featureandcompat::Featurevariants nothing references (about 1300 lines): generated bysrc/css/build-prefixes.js, so the generator would need a filter first.src/js_parser/benches/string_map_vs_hashmap.rs(about 800 lines): a criterion bench, not runtime code..idlfiles undersrc/jsc/bindings/webcoreandwebcrypto: not compiled, but maintained as the reference for the hand-written bindings.bindings.cpp[[ZIG_EXPORT]]wrappers with no Rust caller (JSC__JSValue__isInt32,isNumber,isObject,isUndefined,isUndefinedOrNull,isNull,isCell,isInt32AsAnyInt,jsTDZValue,JSC__JSMap__has,Bun__CallFrame__isFromBunMain, about 45 lines): Remove dead code from the JSC bindings, headers.h, the console builtin, and bun_jsc #40232 edits the same file.ExportRenamer,Futex.rswasm_impl,JsClassDerive, the commented-outfileURLToPathinnode/url.ts, and the unused Cargo dependencies the scan found: already removed by Remove dead code from the inspector protocol package, bun_jsc, bun_install, and the Windows named pipe modules #40557, Remove dead code from bun-uws, bun-usockets, the require.extensions FFI, and unused Cargo dependencies #40294, Remove dead code from the JSC bindings, the codegen scripts, the CI scripts, bun_core, and bun_jsc #40492, or Remove dead code from the JSC bindings, headers.h, the console builtin, and bun_jsc #40232.Candidates the compiler proved live, so they stay:
Display for HookKind(used byname_anonymous_functions.rs),PendingCompile.binding(read invisit/mod.rs),Default for EditorContext(mem::takeinBunObject.rs),CowSliceZ::dupe_maybe_z(used byinto_owned).Areas scanned and found clean:
src/js/**,src/sql,src/valkey,src/runtime/webcore,src/runtime/node,src/runtime/{crypto,server,test_runner,bake,api,timer,ffi,napi,socket,shell},src/http*,src/js_printer,src/runtime/cli,src/install,src/js_parser,src/bundler,src/jsc/*.rs,src/bun_core, 60 small crates, and the C++ bindings outside the files that open dead-code PRs touch.[review] gate passed · iteration 1 · 49 files touched
fails on main (without fix)
passes on PR (with fix)
diff hotspot
gate history · 3 passed · 0 rejected · iteration 1
evidence per changed file