Skip to content

Remove dead code from js_printer, bundler, js_parser, patch, shell, http - #35978

Merged
Jarred-Sumner merged 13 commits into
mainfrom
claude/farm/c47bd45d/dead-code-printer-bundler-shell
Jul 27, 2026
Merged

Jarred-Sumner merged 13 commits into
mainfrom
claude/farm/c47bd45d/dead-code-printer-bundler-shell

Conversation

@robobun

@robobun robobun commented Jul 26, 2026 •

Copy link
Copy Markdown
Collaborator

Net -488 lines across 21 source files. Each item was verified to have zero callers/constructors via rg -w across src/ and build/debug/codegen/ before deletion.

js_printer::Format::Cjs / CjsAscii chain and the REWRITE_ESM_TO_CJS axis (~300 LOC)

Format is constructed at exactly 7 sites (transpiler.rs, jsc_hooks.rs, RuntimeTranspilerStore.rs, AsyncModule.rs, JSTranspiler.rs), all of which pass Esm or EsmAscii. The enum has no repr/serde/bytemuck so it cannot arrive from an integer. With Cjs/CjsAscii gone:

  • fn print_cjs_cold (bundler/transpiler.rs) becomes unreachable: only caller was the Format::Cjs match arm.
  • pub fn print_common_js (js_printer/lib.rs) becomes unreachable: only caller was print_cjs_cold.
  • print_common_js was the only Printer<_, _, _, true, ...> instantiation, so the REWRITE_ESM_TO_CJS const-generic axis is dead: dropped the parameter from the struct and impl, removed print_bundled_export and print_module_export_symbol (only called inside if REWRITE_ESM_TO_CJS { } guards), and unwrapped/deleted the ~10 guarded branches.
  • impl PrintArg for u16 has no callers (every .print(x) passes u8 or &[u8]).

OutputFile::Value::Move / Value::Pending (~65 LOC)

Value is constructed only in OutputFile::init (Buffer/Copy/Saved) and transpiler.rs:build_static_file (Copy). Move and Pending are only matched, never constructed. With them gone:

  • OutputFile::move_to becomes unreachable (only called from the Move arm).
  • FileOperation::get_pathname becomes unreachable (only called from move_to).
  • pub enum Kind + Value::kind() become unreachable (only used in a todo_panic! format string).
  • The manual impl Clone for Value existed only because Pending's payload wasn't Clone; replaced with #[derive(Clone)].
  • OptionsData::File is never constructed (only Buffer/Saved are), which made FileOperation::from_file, FileOperation.fd, and FileOperation.dir dead; FileOperation is now { pathname: Box<[u8]> }.

Other removed items

  • js_parser/parse/parse_entry.rs: 58-line else if p.options.bundle && parts.is_empty() { if false { ... } } arm already commented "permanently disabled"; with no trailing else the whole arm is a no-op.
  • task_tag::ShellIOWriter: doc comment on IOWriter::run_from_main_thread said "No code path enqueues this tag"; confirmed no producer.
  • LsParseError::ShowUsage: ls::parse_opts only returns Ok or Err(IllegalOption).
  • Stage::Connect (http::InternalState): only Pending/Done/Fail are ever assigned.
  • git_diff_preprocess_paths::<SENTINEL>: both call sites pass <false>; dropped the const-generic and its branches.
  • Unused pub use re-exports: h2::LIVE_SESSIONS, ssl_config::GlobalRegistry, install::CacheDirAndSubpath, dev_server::PackedMap, valkey_jsc::ValkeyContext.
  • Stale print_common_js mentions scrubbed from renamer.rs / Chunk.rs / VirtualMachine.rs comments.

Verification

  • bun bd builds.
  • bun run rust:check-all: 10/10 targets pass.
  • bun bd test test/bundler/transpiler/transpiler.test.js: 182 pass.
  • bun bd test test/cli/install/bun-patch.test.ts: 29 pass.
  • bun bd test test/js/node/worker_threads/worker_threads.test.ts: 91 pass.
  • test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts asserts none of these symbols reappear.

Not removed (flagged for followup)

  • RedisError::{InvalidArray, InvalidSimpleString, InvalidErrorString, InvalidNull, InvalidArgument, JSError, JSTerminated} appear unconstructed, but the enum derives strum::EnumString so they could in principle arrive via FromStr; left alone.
  • rm::PromptBehaviour is write-only (only checked against Never) but represents planned -i/-I support; left alone.
  • Ast.runtime_imports (src/ast/ast_result.rs:26) became write-only after 8761a43 removed its two .clone() readers in transpiler.rs. Removing it cascades into bun_ast and bun_js_parser (p.rs:8378/:8393 and the associated comment); deferred to keep this PR's crate footprint bounded.

Scanned areas with nothing confidently dead

src/sql, src/runtime/crypto, src/threading, src/valkey, src/uws, src/runtime/server were scanned and found clean (every pub item has at least one caller). These were already swept by #35002.


[review] gate passed · iteration 1 · 24 files touched

fails on main (without fix)
ASAN without fix: 3 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts
bun test v1.4.0 (c5288fee4)

test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts:
26 |     ["src/js_printer/lib.rs", /fn print_module_export_symbol\b/],
27 |     ["src/bundler/transpiler.rs", /fn print_cjs_cold\b/],
28 |     ["src/bundler/transpiler.rs", /Format::CjsAscii => unreachable/],
29 |   ];
30 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
31 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/js_printer/lib.rs: ^\s*Cjs,$",
+   "src/js_printer/lib.rs: ^\s*CjsAscii,$",
+   "src/js_printer/lib.rs: pub fn print_common_js\b",
+   "src/js_printer/lib.rs: impl PrintArg for u16\b",
+   "src/js_printer/lib.rs: REWRITE_ESM_TO_CJS",
+   "src/js_printer/lib.rs: fn print_bundled_export\b",
+   "src/js_printer/lib.rs: fn print_module_export_symbol\b",
+   "src/bundler/transpiler.rs: fn print_cjs_cold\b",
+  
... (truncated)

release without fix: 3 FAILED
bun test v1.4.0-canary.1 (924ef2542)

test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts:
26 |     ["src/js_printer/lib.rs", /fn print_module_export_symbol\b/],
27 |     ["src/bundler/transpiler.rs", /fn print_cjs_cold\b/],
28 |     ["src/bundler/transpiler.rs", /Format::CjsAscii => unreachable/],
29 |   ];
30 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
31 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/js_printer/lib.rs: ^\s*Cjs,$",
+   "src/js_printer/lib.rs: ^\s*CjsAscii,$",
+   "src/js_printer/lib.rs: pub fn print_common_js\b",
+   "src/js_printer/lib.rs: impl PrintArg for u16\b",
+   "src/js_printer/lib.rs: REWRITE_ESM_TO_CJS",
+   "src/js_printer/lib.rs: fn print_bundled_export\b",
+   "src/js_printer/lib.rs: fn print_module_export_symbol\b",
+   "src/bundler/transpiler.rs: fn print_cjs_cold\b",
+   "src/bundler/transpiler.rs: Format::CjsAscii => unreachable",
+ ]

- Expected  - 1
+ Received  + 11

      at <anonymous> (/workspace/bun/test/internal/source-lints/dead-symbols-printer-bundler
... (truncated)
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/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts
bun test v1.4.0 (c5288fee4)

test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts:
(pass) dead js_printer Format::Cjs chain does not reappear [44.96ms]
(pass) dead OutputFile::Value variants do not reappear [13.62ms]
(pass) dead shell / http / patch items do not reappear [27.42ms]

 3 pass
 0 fail
 3 expect() calls
Ran 3 tests across 1 file. [2.54s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 860ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/7] gen bake.{client,server,error}.js
-> bake.client.js, bake.server.js, bake.error.js
[2/7] gen generated_host_exports.rs
generated_host_exports.rs: 94 exports (host=3, lazy=10, generic=81, rust=0); 240 extern-C blocks audited
[2/7] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19)

�[1m�[92m   Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core)
�[1m�[92m   Compiling�[0m bun_errno v0.0.0 (/workspace/bun/src/errno)
�[1m�[92m   Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/src/ptr)
�[1m�[92m   Compiling�[0m bun_boringssl_sys v0.0.0 (/workspace/bun/src/boringssl_sys)
�[1m�[92m   Compiling�[0m bun_safety v0.0.0 (/workspace/bun/src/safety)
�[1m�[92m   Compiling�[0m bun_zlib_sys v0.0.0 (/workspace/bun/src/zlib_sys)
�[1m�[92m   Compiling�[0m bun_cares_sys v0.0.0 (/workspace/bun/src/cares_sys)
�[1m�[92m   Compiling�[0m bun_zstd v0.0.0 (/workspace/bun/src/zstd)
�[1m�[92m   Compiling�[0m
... (truncated)
diff hotspot
src/bundler/OutputFile.rs                          | 121 +--------
 src/bundler/transpiler.rs                          |  87 +------
 src/event_loop/ConcurrentTask.rs                   |   1 -
 src/http/H2Client.rs                               |   5 +-
 src/http/HTTPThread.rs                             |   4 +-
 src/http/InternalState.rs                          |   1 -
 src/http/ssl_config.rs                             |   2 -
 src/install/PackageManager/patchPackage.rs         |   2 +-
 src/install/lib.rs                                 |   1 -
 src/js_parser/parse/parse_entry.rs                 |  58 -----
 src/js_printer/lib.rs                              | 278 ++-------------------
 src/js_printer/renamer.rs                          |   2 +-
 src/jsc/VirtualMachine.rs                          |   2 +-
 src/patch/lib.rs                                   |  41 +--
 src/runtime/api/output_file_jsc.rs                 |  33 +--
 src/runtime/bake/dev_server/mod.rs                 |   1 -
 src/runtime/dispatch.rs                            |   8 +-
 src/runtime/shell/IOWriter.rs                      |   7 -
 src/runtime/shell/builtin/ls.rs                    |  35 +--
 src/runtime/valkey_jsc/mod.rs                      |   9 -
 src/runtime/valkey_jsc/valkey.rs                   |   2 -
 src/runtime/webcore/fetch.rs                       |   2 +-
 src/sourcemap/Chunk.rs                             |  10 +-
 .../dead-symbols-printer-bundler-shell.test.ts     |  68 +++++
 24 files changed, 140 insertions(+), 640 deletions(-)

gate history · 9 passed · 0 rejected · iteration 1

evidence per changed file
file                                        reads  edits  tests
src/bundler/OutputFile.rs                       6      5      0
src/bundler/transpiler.rs                       5      5      0
src/event_loop/ConcurrentTask.rs                1      1      0
src/http/H2Client.rs                            2      2      0
src/http/HTTPThread.rs                          1      1      0
src/http/InternalState.rs                       1      1      0
src/http/ssl_config.rs                          1      1      0
src/install/PackageManager/patchPackage.rs      1      1      0
src/install/lib.rs                              1      1      0
src/js_parser/parse/parse_entry.rs              2      2      0
src/js_printer/lib.rs                           8      6      0
src/js_printer/renamer.rs                       2      3      0
src/jsc/VirtualMachine.rs                       1      1      0
src/patch/lib.rs                                2      3      0
src/runtime/api/output_file_jsc.rs              3      3      0
src/runtime/bake/dev_server/mod.rs              1      1      0
(+ 8 more files)

js_printer::Format::Cjs / Format::CjsAscii are never constructed (only Esm
and EsmAscii are), which makes print_common_js and Transpiler::print_cjs_cold
unreachable. This also drops the IS_COMMON_JS=true Printer monomorphization
from .text.

OutputFile::Value::Move and Value::Pending are never constructed (only
Buffer/Copy/Saved/Noop are produced by OutputFile::init and transpiler.rs),
which makes move_to, get_pathname, and the Kind enum unreachable.

Also removed:
- js_parser parse_entry.rs 'if false {}' block (marked permanently disabled)
- impl PrintArg for u16 (no u16 ever reaches .print())
- task_tag::ShellIOWriter (documented as never enqueued)
- LsParseError::ShowUsage (parse_opts only returns IllegalOption)
- Stage::Connect (never assigned)
- git_diff_preprocess_paths SENTINEL const-generic (only <false> instantiated)
- 5 unused pub re-exports

Verified via rg across src/ and build/debug/codegen/; rust:check-all passes
on all 10 targets.
@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

The pull request removes obsolete printer and bundler output paths, simplifies runtime dispatch and output conversion, narrows several public APIs, updates patch and parser handling, and adds source-lint tests preventing removed symbols from returning.

Obsolete code-path removal

Layer / File(s) Summary
Printer and bundler output simplification
src/js_printer/lib.rs, src/bundler/OutputFile.rs, src/bundler/transpiler.rs, src/sourcemap/Chunk.rs
The printer removes CommonJS rewriting support and related helpers, while OutputFile retains only buffer, copy, noop, and saved representations.
Runtime dispatch and output handling
src/runtime/api/output_file_jsc.rs, src/runtime/dispatch.rs, src/runtime/shell/..., src/event_loop/ConcurrentTask.rs
Output conversion uses pathname-based copies, shell writer dispatch is removed, and ls parsing returns offending option bytes directly.
Parser, patch, and public API cleanup
src/js_parser/..., src/patch/lib.rs, src/http/..., src/install/..., src/runtime/valkey_jsc/..., src/runtime/bake/dev_server/mod.rs, src/runtime/webcore/fetch.rs
Unused parser logic and patch generics are removed, and multiple public variants, aliases, modules, and re-exports are narrowed or deleted.
Dead-symbol regression guards
test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts
Source scans assert that removed printer, bundler, shell, HTTP, patch, parser, and export symbols do not reappear.

Suggested reviewers: jarred-sumner

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
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 matches the PR’s main theme: removing dead code across several Rust modules.
Description check ✅ Passed The description covers what changed and includes verification results, though it does not use the template’s exact headings.

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

@robobun

robobun commented Jul 26, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 1:35 AM PT - Jul 27th, 2026

@Jarred-Sumner, your commit ec52bc4 is building: #83218

Comment thread src/js_parser/parse/parse_entry.rs Outdated
The condition is side-effect-free (bool field + Vec::is_empty) and there
is no trailing else, so with the body gone the whole arm is dead along
with its stale comment.
Comment thread src/bundler/transpiler.rs
Comment thread src/js_printer/lib.rs
Comment thread src/bundler/OutputFile.rs Outdated
…le Clone residue

print_common_js was the only Printer instantiation with
REWRITE_ESM_TO_CJS=true; the three surviving PrinterType aliases all
hard-code it to false. That makes every 'if REWRITE_ESM_TO_CJS { }'
branch dead, along with print_bundled_export and
print_module_export_symbol (only called from inside those branches).
Remove the const-generic parameter entirely.

OutputFile: the manual 'impl Clone for Value' existed only because
Value::Pending's payload wasn't Clone; with Pending gone, all remaining
payloads derive Clone. Also drop the stale 'move the file' header
comment and the stale print_common_js mentions in renamer.rs /
Chunk.rs / VirtualMachine.rs.
Comment thread src/js_printer/lib.rs
Comment thread src/sourcemap/Chunk.rs
Comment thread src/runtime/valkey_jsc/mod.rs
Comment thread src/runtime/shell/builtin/ls.rs Outdated
Comment thread src/sourcemap/Chunk.rs
- valkey_jsc: drop the ValkeyContext ZST module and its sibling re-export
  in valkey.rs (zero consumers; rare_data.rs already documents the
  backing field was removed).
- sourcemap/Chunk.rs: scrub the second stale printCommonJS mention at
  line_offset_tables doc.
- shell/ls: LsParseError is now single-variant after ShowUsage was
  removed; inline to Result<Option<usize>, Box<[u8]>>.
Comment thread src/runtime/shell/builtin/ls.rs
Comment thread src/sourcemap/Chunk.rs
Comment thread src/bundler/transpiler.rs Outdated
Comment thread src/bundler/OutputFile.rs
…OptionsData::File

FileOperation.dir's only reader was the deleted move_to. Tracing that:
OptionsData::File is never constructed (only Buffer and Saved are), so
the OutputFile::init arm that set op.dir/op.fd via from_file is dead,
which leaves FileOperation.fd always Fd::INVALID at the one remaining
construction site. Drop dir, fd, from_file, the Default impl, and the
OptionsData::File variant; simplify the two copy.fd.is_valid() branches
in output_file_jsc.rs to the Path arm.

Also fix the two Printer<W,A,B,C,D,E> arity comments in transpiler.rs
to reflect the dropped const-generic axis.
Comment thread src/bundler/transpiler.rs
Comment thread src/http/ssl_config.rs
Comment thread src/bundler/OutputFile.rs
- transpiler.rs: drop the two 'same as the Cjs arm' shorthands that
  pointed at the deleted print_cjs_cold body (print_with_source_map_maybe
  already documents print_arena).
- HTTPThread.rs / fetch.rs: rename the GlobalRegistry alias references in
  comments to the surviving ssl_config::global_registry path.
- OutputFile.rs: dest_path can now move options.output_path; the .clone()
  was only needed for the deleted OptionsData::File arm's later borrow.
Comment thread src/http/HTTPThread.rs
Comment thread src/bundler/OutputFile.rs Outdated
The manual impl Default existed to init the deleted fd/dir fields to
Fd::INVALID; 3a84fbc converted it to a derive but also removed both
..Default::default() consumers in the same commit.
Comment thread src/js_printer/lib.rs
Comment thread src/bundler/transpiler.rs
Comment thread src/http/H2Client.rs
…ment scrubs

Options.runtime_imports had its only reader in the deleted
'if REWRITE_ESM_TO_CJS && is_export' block in print_decl_stmt. Drop the
field, its default, the two ast.runtime_imports.clone() write sites in
transpiler.rs, the forwarding comment that described the plumbing, and
the now-unused 'use js_ast::runtime;' import.

Also:
- transpiler.rs:2557 print_expr<true,false,true,false,true> stale arity
- H2Client.rs plural 'aliases' comment now describes one alias
Comment thread src/http/H2Client.rs
@robobun

robobun commented Jul 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

Diff is ready for review: net -500 across 23 source files (+1 source-lint test), all review threads resolved. Both automated reviewers returned "no bugs found".

The full transitive chain from Format::Cjs being unconstructed turned out to be deep: print_common_js → the REWRITE_ESM_TO_CJS const-generic axis → print_bundled_export / print_module_export_symbol → Options.runtime_imports. Similarly Value::Move/Pending → move_to → FileOperation.dir/fd → OptionsData::File → from_file. Each layer was verified via rg -w across src/ and build/debug/codegen/.

CI is green on the diff. Build #83126 (the re-roll): 194/196 jobs passed; the only test failures are all marked [flaky] by the scraper (passed on retry) and none touch code in this PR: complex-workspace.test.ts (install registry), webview-chrome.test.ts, napi.test.ts, test-http-server-connections-checking-leak.js, 20144.test.ts. The worker ExceptionScope assertion seen once on build #83120 did not recur on the re-roll.

bun bd, rust:check-all (10/10 targets), and transpiler/bundler/patch/worker_threads smoke tests all pass locally. Ready to merge.

Comment thread src/bundler/transpiler.rs

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/js_printer/renamer.rs`:
- Around line 101-103: Update the ownership comment above NoOpRenamer in
renamer.rs to acknowledge that it is constructed by both print_ast and
print_json, while preserving the accurate explanation that each caller provides
an owned Map whose contents can be safely dropped.

In `@src/patch/lib.rs`:
- Around line 1731-1733: Replace the vague comment above the
slashes_to_posix_in_place call with a concise, professional explanation of the
durable Windows path-normalization invariant that requires converting
backslashes in old_folder_ to POSIX separators before copying or using the path.

In `@test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts`:
- Around line 18-29: Update the dead-symbol regex checks in the “dead js_printer
Format::Cjs chain does not reappear” test and the additional affected checks to
tolerate Rust visibility, whitespace, and line breaks. Match tokens such as
optional `pub(...)` before functions, `if false` with arbitrary whitespace
before the brace, and multiline `pub use` declarations, while preserving each
check’s intended symbol detection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5054520a-2d84-42cf-847d-58d8b37a2c70

📥 Commits

Reviewing files that changed from the base of the PR and between c7233fb and 8acea6e.

📒 Files selected for processing (24)
  • src/bundler/OutputFile.rs
  • src/bundler/transpiler.rs
  • src/event_loop/ConcurrentTask.rs
  • src/http/H2Client.rs
  • src/http/HTTPThread.rs
  • src/http/InternalState.rs
  • src/http/ssl_config.rs
  • src/install/PackageManager/patchPackage.rs
  • src/install/lib.rs
  • src/js_parser/parse/parse_entry.rs
  • src/js_printer/lib.rs
  • src/js_printer/renamer.rs
  • src/jsc/VirtualMachine.rs
  • src/patch/lib.rs
  • src/runtime/api/output_file_jsc.rs
  • src/runtime/bake/dev_server/mod.rs
  • src/runtime/dispatch.rs
  • src/runtime/shell/IOWriter.rs
  • src/runtime/shell/builtin/ls.rs
  • src/runtime/valkey_jsc/mod.rs
  • src/runtime/valkey_jsc/valkey.rs
  • src/runtime/webcore/fetch.rs
  • src/sourcemap/Chunk.rs
  • test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts
💤 Files with no reviewable changes (9)
  • src/runtime/bake/dev_server/mod.rs
  • src/runtime/valkey_jsc/valkey.rs
  • src/runtime/shell/IOWriter.rs
  • src/js_parser/parse/parse_entry.rs
  • src/http/ssl_config.rs
  • src/install/lib.rs
  • src/http/InternalState.rs
  • src/event_loop/ConcurrentTask.rs
  • src/runtime/valkey_jsc/mod.rs

Comment thread src/js_printer/renamer.rs Outdated
Comment thread src/patch/lib.rs Outdated
Comment thread test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts Outdated
…mment

The renamer.rs scrub in 48ce811 dropped print_common_js but missed that
print_json also constructs NoOpRenamer. Also replace the pre-existing
crude comment in git_diff_preprocess_paths with a plain description of
the invariant.
Comment thread src/runtime/api/output_file_jsc.rs Outdated
3a84fbc converted the multi-arm match to a single if-let; the comment
described the old plural shape.

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

No bugs found. Deferring to a maintainer given the scope — ~500 LOC removed across 24 files including the Printer const-generic arity change in js_printer/lib.rs and OutputFile::Value/OptionsData variant deletions, which are load-bearing enough on the runtime print path that a human should confirm the Format::Cjs-unconstructed and FileOperation.fd-never-set claims.

What was reviewed:

  • REWRITE_ESM_TO_CJS axis removal: every unwrapped guard (SFunction/SClass/SExportClause/ERequireString/print_decl_stmt) is behavior-preserving for the surviving false value; MAY_HAVE_MODULE_INFO reduction is correct.
  • output_file_jsc.rs copy.fd branch removal traced to the sole Value::Copy producer in transpiler.rs:build_static_file, which never set fd.
  • task_tag::ShellIOWriter removal: COUNT assert bumped 97→96, dispatch arm and run_from_main_thread no-op removed together; no producer found.
  • git_diff_preprocess_paths Windows path: .to_vec() + slashes_to_posix_in_place matches the old SENTINEL=false behavior.
Extended reasoning...

Overview

Net -488 lines across 24 files. Three transitive dead-code chains: (1) js_printer::Format::Cjs/CjsAscii → print_cjs_cold → print_common_js → the REWRITE_ESM_TO_CJS const-generic axis on Printer (~280 LOC in js_printer/lib.rs, plus PrinterType alias updates); (2) OutputFile::Value::{Move,Pending} / OptionsData::File → move_to/from_file/FileOperation.{fd,dir}/Kind (~120 LOC across OutputFile.rs / output_file_jsc.rs / transpiler.rs); (3) assorted single-item removals (task_tag::ShellIOWriter, Stage::Connect, LsParseError, git_diff_preprocess_paths<SENTINEL>, five pub use re-exports, an if false block in parse_entry.rs). Plus ~14 stale-comment scrubs across the review cycle and a new source-lint test.

Security risks

None. Pure dead-code deletion; no new inputs, no parsing changes, no permission/auth/crypto surface touched. The patch/lib.rs change only drops an unused const-generic branch.

Level of scrutiny

High. js_printer/lib.rs is the runtime's JS output path — every bun run / transpiled module flows through it — and the change alters the Printer struct's const-generic arity and unwraps ~10 if REWRITE_ESM_TO_CJS guards. dispatch.rs is the event-loop hot path with a compile-time COUNT assert. OutputFile is the bundler's output handle. Each individual deletion is mechanically verifiable (and the author did verify via rg -w across src/ + codegen/), but the aggregate is large enough and the printer hot enough that a maintainer should sign off on the two root claims: that Format is only ever constructed as Esm/EsmAscii at 7 named sites, and that OptionsData::File / Value::Move/Pending have zero constructors.

Other factors

  • The PR has been through ~14 review rounds (all mine were stale-comment residue, all addressed; CodeRabbit's substantive comments addressed, one withdrawn). All threads resolved.
  • rust:check-all 10/10, transpiler/patch/worker_threads tests pass locally per the description; CI on the latest push was blocked by fleet infra, not test failures.
  • The Ast.runtime_imports write-only field created by 8761a43 is documented as a followup rather than fixed here — reasonable scope boundary.
  • The source-lint test follows the existing test/internal/source-lints/dead-symbols-*.test.ts pattern.

Not approving because this exceeds the "simple, mechanical, or obvious" bar: the printer const-generic arity change and the enum-variant-unconstructed claims are the kind of thing a maintainer with repo history should confirm, even though I found nothing wrong with them.

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

No bugs found. All prior review threads (mine, CodeRabbit, comment-cop) are resolved and the removals check out mechanically — rust:check-all passing on 10 targets is the real proof. Deferring to a human because the scope is large: -488 lines across 21 files, including dropping the REWRITE_ESM_TO_CJS const-generic axis from Printer and a slot from the task_tag dispatch table, which are design-level commitments a maintainer should sign off on.

What was reviewed:

  • Confirmed the many Format::Cjs grep hits in src/ are the bundler's options::Format/OutputFormat enum, not the removed js_printer::Format::Cjs.
  • FileOperation.fd removal in output_file_jsc.rs — fd was only ever Fd::INVALID (sole constructor is build_static_file, which never set it), so the Path-only branch is behaviour-preserving.
  • task_tag::ShellIOWriter removal + COUNT 97→96 — no producer, and dispatch.rs const-assert is updated in lockstep.
  • CacheDirAndSubpath / PackedMap re-export removals leave the underlying types intact; no cross-crate consumers (build passes).
Extended reasoning...

Overview

Net -488 lines across 21 source files + 1 new source-lint test. Two large transitive chains: (1) js_printer::Format::Cjs/CjsAscii → print_common_js → the REWRITE_ESM_TO_CJS const-generic axis on Printer → print_bundled_export/print_module_export_symbol/Options.runtime_imports; (2) OutputFile::Value::{Move,Pending} → move_to/Kind/manual Clone → OptionsData::File → FileOperation.{fd,dir}. Plus a scattering of unconstructed enum variants (Stage::Connect, LsParseError::ShowUsage), an unused task tag (ShellIOWriter), a dead const-generic (git_diff_preprocess_paths::<SENTINEL>), five unused pub use re-exports, an if false { } block in parse_entry.rs, and ~15 stale-comment scrubs accumulated over the review cycle.

Security risks

None. Pure dead-code removal; no new inputs, no relaxed validation, no changed error handling on live paths.

Level of scrutiny

High — not because the changes are subtle, but because of scope. The compiler + rust:check-all (10 targets) provide strong structural guarantees: any missed match arm, wrong const-generic arity, or dangling cross-crate reference would fail to build. I spot-checked the highest-risk claims: the Format::Cjs grep across src/ returns ~30 hits, but every one is options::Format/bundle_opts::Format/OutputFormat/ModuleFormat (the bundler's output-format config enums), not the removed js_printer::Format print-path enum. Stage::Connect has zero remaining references. The output_file_jsc.rs copy.fd.is_valid() branch removal is safe because the only Value::Copy constructor (build_static_file) never populated fd.

That said, dropping the REWRITE_ESM_TO_CJS axis from Printer and removing a task_tag slot are design commitments (they close off a code path someone may have intended to re-enable), and 21 files touching the printer/bundler/dispatch hot paths is above my threshold for approving without a maintainer glance.

Other factors

The PR went through ~15 review iterations, all of which surfaced only stale-comment residue (plural→singular, arity counts, renamed aliases) — no behavioural findings. All inline threads are resolved. The bug-hunting system found nothing this run. Ast.runtime_imports (made write-only by 8761a43) is explicitly deferred to a followup with a stated reason. The new source-lint test follows the existing test/internal/source-lints/dead-symbols-*.test.ts convention.

@Jarred-Sumner
Jarred-Sumner merged commit e77f5a9 into main Jul 27, 2026
4 of 9 checks passed
@Jarred-Sumner
Jarred-Sumner deleted the claude/farm/c47bd45d/dead-code-printer-bundler-shell branch July 27, 2026 08:36

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

No bugs found; deferring given the size (−488 lines across 23 files in js_printer / bundler / transpiler / event-loop dispatch) — worth a maintainer sign-off rather than a bot approval.

What was reviewed:

  • Verified Format::Cjs/CjsAscii are unconstructed at all 7 sites and the REWRITE_ESM_TO_CJS axis, print_common_js, print_bundled_export, Options.runtime_imports cascade is fully dead.
  • Verified OutputFile::Value::{Move,Pending} / OptionsData::File are unconstructed and the FileOperation.{fd,dir} / move_to / Kind cascade has no remaining readers (including output_file_jsc.rs's copy.fd branch).
  • Checked task_tag::ShellIOWriter has no producer, Stage::Connect is never assigned, and the removed pub use re-exports (LIVE_SESSIONS, GlobalRegistry, CacheDirAndSubpath, PackedMap, ValkeyContext) have no external references.
  • Note: ec52bc4 dropped the source-lint test; the PR description's Verification section still references it.
Extended reasoning...

Overview

This PR removes ~488 lines of provably-dead code across 23 files: the js_printer::Format::Cjs/CjsAscii chain and its REWRITE_ESM_TO_CJS const-generic axis (~300 LOC), OutputFile::Value::{Move,Pending} and the OptionsData::File/FileOperation.{fd,dir} cascade (~65 LOC), a permanently-disabled if false block in parse_entry.rs, an unreachable task_tag::ShellIOWriter dispatch arm, unused enum variants (LsParseError::ShowUsage, Stage::Connect), a dead SENTINEL const-generic in git_diff_preprocess_paths, and five unused pub use re-exports. It also scrubs ~15 stale comment references to the deleted code.

Security risks

None identified. This is pure deletion of unreferenced code paths; no new logic, no input handling, no auth/crypto surface. The only security-adjacent file touched (ssl_config.rs) drops a single unused re-export alias.

Level of scrutiny

High — the changes touch core hot-path infrastructure (js_printer, bundler/transpiler, event-loop dispatch.rs, ConcurrentTask tag table). Dead-code removal is low-risk when correct but requires proving each item is truly unreferenced across all cfg-gated targets and codegen output. The author verified via rg -w across src/ and build/debug/codegen/, and rust:check-all passes on 10/10 targets, which the compiler enforces for most items (removed enum variants/functions cannot compile if referenced).

Other factors

  • I left 17 inline comments over the review cycle (cascading residue: REWRITE_ESM_TO_CJS axis, FileOperation.dir, ValkeyContext module, LsParseError collapse, ~14 stale-comment scrubs); all were addressed and all threads are resolved.
  • CodeRabbit's three findings were addressed or withdrawn.
  • The Ast.runtime_imports write-only residue is documented under "Not removed (flagged for followup)" since it cascades into two more crates.
  • A maintainer pushed ec52bc4 deleting the source-lint test that the PR description still references under Verification; this leaves the PR with no test file, though for pure dead-code removal the compiler's exhaustiveness check on 10/10 targets is the substantive guard. The stale description line is cosmetic.
  • CI build #83218 is running on the latest commit.

Given the breadth (23 files, several core subsystems) and that a maintainer is already engaged with the branch, deferring rather than bot-approving.

Jarred-Sumner added a commit that referenced this pull request Jul 27, 2026
…ttp (#35978)

Net -488 lines across 21 source files. Each item was verified to have
zero callers/constructors via `rg -w` across `src/` and
`build/debug/codegen/` before deletion.

## `js_printer::Format::Cjs` / `CjsAscii` chain and the
`REWRITE_ESM_TO_CJS` axis (~300 LOC)

`Format` is constructed at exactly 7 sites (transpiler.rs, jsc_hooks.rs,
RuntimeTranspilerStore.rs, AsyncModule.rs, JSTranspiler.rs), all of
which pass `Esm` or `EsmAscii`. The enum has no `repr`/serde/bytemuck so
it cannot arrive from an integer. With `Cjs`/`CjsAscii` gone:

- `fn print_cjs_cold` (bundler/transpiler.rs) becomes unreachable: only
caller was the `Format::Cjs` match arm.
- `pub fn print_common_js` (js_printer/lib.rs) becomes unreachable: only
caller was `print_cjs_cold`.
- `print_common_js` was the only `Printer<_, _, _, true, ...>`
instantiation, so the `REWRITE_ESM_TO_CJS` const-generic axis is dead:
dropped the parameter from the struct and impl, removed
`print_bundled_export` and `print_module_export_symbol` (only called
inside `if REWRITE_ESM_TO_CJS { }` guards), and unwrapped/deleted the
~10 guarded branches.
- `impl PrintArg for u16` has no callers (every `.print(x)` passes `u8`
or `&[u8]`).

## `OutputFile::Value::Move` / `Value::Pending` (~65 LOC)

`Value` is constructed only in `OutputFile::init` (Buffer/Copy/Saved)
and `transpiler.rs:build_static_file` (Copy). `Move` and `Pending` are
only matched, never constructed. With them gone:

- `OutputFile::move_to` becomes unreachable (only called from the `Move`
arm).
- `FileOperation::get_pathname` becomes unreachable (only called from
`move_to`).
- `pub enum Kind` + `Value::kind()` become unreachable (only used in a
`todo_panic!` format string).
- The manual `impl Clone for Value` existed only because `Pending`'s
payload wasn't `Clone`; replaced with `#[derive(Clone)]`.
- `OptionsData::File` is never constructed (only `Buffer`/`Saved` are),
which made `FileOperation::from_file`, `FileOperation.fd`, and
`FileOperation.dir` dead; `FileOperation` is now `{ pathname: Box<[u8]>
}`.

## Other removed items

- `js_parser/parse/parse_entry.rs`: 58-line `else if p.options.bundle &&
parts.is_empty() { if false { ... } }` arm already commented
"permanently disabled"; with no trailing `else` the whole arm is a
no-op.
- `task_tag::ShellIOWriter`: doc comment on
`IOWriter::run_from_main_thread` said "No code path enqueues this tag";
confirmed no producer.
- `LsParseError::ShowUsage`: `ls::parse_opts` only returns `Ok` or
`Err(IllegalOption)`.
- `Stage::Connect` (`http::InternalState`): only `Pending`/`Done`/`Fail`
are ever assigned.
- `git_diff_preprocess_paths::<SENTINEL>`: both call sites pass
`<false>`; dropped the const-generic and its branches.
- Unused `pub use` re-exports: `h2::LIVE_SESSIONS`,
`ssl_config::GlobalRegistry`, `install::CacheDirAndSubpath`,
`dev_server::PackedMap`, `valkey_jsc::ValkeyContext`.
- Stale `print_common_js` mentions scrubbed from renamer.rs / Chunk.rs /
VirtualMachine.rs comments.

## Verification

- `bun bd` builds.
- `bun run rust:check-all`: 10/10 targets pass.
- `bun bd test test/bundler/transpiler/transpiler.test.js`: 182 pass.
- `bun bd test test/cli/install/bun-patch.test.ts`: 29 pass.
- `bun bd test test/js/node/worker_threads/worker_threads.test.ts`: 91
pass.
-
`test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts`
asserts none of these symbols reappear.

## Not removed (flagged for followup)

- `RedisError::{InvalidArray, InvalidSimpleString, InvalidErrorString,
InvalidNull, InvalidArgument, JSError, JSTerminated}` appear
unconstructed, but the enum derives `strum::EnumString` so they could in
principle arrive via `FromStr`; left alone.
- `rm::PromptBehaviour` is write-only (only checked against `Never`) but
represents planned `-i`/`-I` support; left alone.
- `Ast.runtime_imports` (src/ast/ast_result.rs:26) became write-only
after 8761a43 removed its two `.clone()` readers in transpiler.rs.
Removing it cascades into `bun_ast` and `bun_js_parser` (p.rs:8378/:8393
and the associated comment); deferred to keep this PR's crate footprint
bounded.

## Scanned areas with nothing confidently dead

`src/sql`, `src/runtime/crypto`, `src/threading`, `src/valkey`,
`src/uws`, `src/runtime/server` were scanned and found clean (every pub
item has at least one caller). These were already swept by #35002.

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

---

**[review]** gate passed · iteration 1 · 24 files touched

<details><summary>fails on main (without fix)</summary>

```console
ASAN without fix: 3 FAILED
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/mechgate.xml" test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts
bun test v1.4.0 (c5288fe)

test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts:
26 |     ["src/js_printer/lib.rs", /fn print_module_export_symbol\b/],
27 |     ["src/bundler/transpiler.rs", /fn print_cjs_cold\b/],
28 |     ["src/bundler/transpiler.rs", /Format::CjsAscii => unreachable/],
29 |   ];
30 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
31 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/js_printer/lib.rs: ^\s*Cjs,$",
+   "src/js_printer/lib.rs: ^\s*CjsAscii,$",
+   "src/js_printer/lib.rs: pub fn print_common_js\b",
+   "src/js_printer/lib.rs: impl PrintArg for u16\b",
+   "src/js_printer/lib.rs: REWRITE_ESM_TO_CJS",
+   "src/js_printer/lib.rs: fn print_bundled_export\b",
+   "src/js_printer/lib.rs: fn print_module_export_symbol\b",
+   "src/bundler/transpiler.rs: fn print_cjs_cold\b",
+  
... (truncated)

release without fix: 3 FAILED
bun test v1.4.0-canary.1 (924ef25)

test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts:
26 |     ["src/js_printer/lib.rs", /fn print_module_export_symbol\b/],
27 |     ["src/bundler/transpiler.rs", /fn print_cjs_cold\b/],
28 |     ["src/bundler/transpiler.rs", /Format::CjsAscii => unreachable/],
29 |   ];
30 |   const resurrected = checks.filter(([file, re]) => re.test(src(file))).map(([file, re]) => `${file}: ${re.source}`);
31 |   expect(resurrected).toEqual([]);
                           ^
error: expect(received).toEqual(expected)

- []
+ [
+   "src/js_printer/lib.rs: ^\s*Cjs,$",
+   "src/js_printer/lib.rs: ^\s*CjsAscii,$",
+   "src/js_printer/lib.rs: pub fn print_common_js\b",
+   "src/js_printer/lib.rs: impl PrintArg for u16\b",
+   "src/js_printer/lib.rs: REWRITE_ESM_TO_CJS",
+   "src/js_printer/lib.rs: fn print_bundled_export\b",
+   "src/js_printer/lib.rs: fn print_module_export_symbol\b",
+   "src/bundler/transpiler.rs: fn print_cjs_cold\b",
+   "src/bundler/transpiler.rs: Format::CjsAscii => unreachable",
+ ]

- Expected  - 1
+ Received  + 11

      at <anonymous> (/workspace/bun/test/internal/source-lints/dead-symbols-printer-bundler
... (truncated)
```

</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/dead-symbols-printer-bundler-shell.test.ts
bun test v1.4.0 (c5288fe)

test/internal/source-lints/dead-symbols-printer-bundler-shell.test.ts:
(pass) dead js_printer Format::Cjs chain does not reappear [44.96ms]
(pass) dead OutputFile::Value variants do not reappear [13.62ms]
(pass) dead shell / http / patch items do not reappear [27.42ms]

 3 pass
 0 fail
 3 expect() calls
Ran 3 tests across 1 file. [2.54s]
__F:0:S:0

release with fix: all passed
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 860ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/7] gen bake.{client,server,error}.js
-> bake.client.js, bake.server.js, bake.error.js
[2/7] gen generated_host_exports.rs
generated_host_exports.rs: 94 exports (host=3, lazy=10, generic=81, rust=0); 240 extern-C blocks audited
[2/7] cargo bun_bin → libbun_rust.a (--target x86_64-unknown-linux-gnu)

  nightly-2026-07-20-x86_64-unknown-linux-gnu unchanged - rustc 1.99.0-nightly (9f36de775 2026-07-19)

�[1m�[92m   Compiling�[0m bun_core v0.0.0 (/workspace/bun/src/bun_core)
�[1m�[92m   Compiling�[0m bun_errno v0.0.0 (/workspace/bun/src/errno)
�[1m�[92m   Compiling�[0m bun_ptr v0.0.0 (/workspace/bun/src/ptr)
�[1m�[92m   Compiling�[0m bun_boringssl_sys v0.0.0 (/workspace/bun/src/boringssl_sys)
�[1m�[92m   Compiling�[0m bun_safety v0.0.0 (/workspace/bun/src/safety)
�[1m�[92m   Compiling�[0m bun_zlib_sys v0.0.0 (/workspace/bun/src/zlib_sys)
�[1m�[92m   Compiling�[0m bun_cares_sys v0.0.0 (/workspace/bun/src/cares_sys)
�[1m�[92m   Compiling�[0m bun_zstd v0.0.0 (/workspace/bun/src/zstd)
�[1m�[92m   Compiling�[0m
... (truncated)
```

</details>

<details><summary>diff hotspot</summary>

```
src/bundler/OutputFile.rs                          | 121 +--------
 src/bundler/transpiler.rs                          |  87 +------
 src/event_loop/ConcurrentTask.rs                   |   1 -
 src/http/H2Client.rs                               |   5 +-
 src/http/HTTPThread.rs                             |   4 +-
 src/http/InternalState.rs                          |   1 -
 src/http/ssl_config.rs                             |   2 -
 src/install/PackageManager/patchPackage.rs         |   2 +-
 src/install/lib.rs                                 |   1 -
 src/js_parser/parse/parse_entry.rs                 |  58 -----
 src/js_printer/lib.rs                              | 278 ++-------------------
 src/js_printer/renamer.rs                          |   2 +-
 src/jsc/VirtualMachine.rs                          |   2 +-
 src/patch/lib.rs                                   |  41 +--
 src/runtime/api/output_file_jsc.rs                 |  33 +--
 src/runtime/bake/dev_server/mod.rs                 |   1 -
 src/runtime/dispatch.rs                            |   8 +-
 src/runtime/shell/IOWriter.rs                      |   7 -
 src/runtime/shell/builtin/ls.rs                    |  35 +--
 src/runtime/valkey_jsc/mod.rs                      |   9 -
 src/runtime/valkey_jsc/valkey.rs                   |   2 -
 src/runtime/webcore/fetch.rs                       |   2 +-
 src/sourcemap/Chunk.rs                             |  10 +-
 .../dead-symbols-printer-bundler-shell.test.ts     |  68 +++++
 24 files changed, 140 insertions(+), 640 deletions(-)
```

</details>

**gate history** · 9 passed · 0 rejected · iteration 1

<details><summary>evidence per changed file</summary>

```
file                                        reads  edits  tests
src/bundler/OutputFile.rs                       6      5      0
src/bundler/transpiler.rs                       5      5      0
src/event_loop/ConcurrentTask.rs                1      1      0
src/http/H2Client.rs                            2      2      0
src/http/HTTPThread.rs                          1      1      0
src/http/InternalState.rs                       1      1      0
src/http/ssl_config.rs                          1      1      0
src/install/PackageManager/patchPackage.rs      1      1      0
src/install/lib.rs                              1      1      0
src/js_parser/parse/parse_entry.rs              2      2      0
src/js_printer/lib.rs                           8      6      0
src/js_printer/renamer.rs                       2      3      0
src/jsc/VirtualMachine.rs                       1      1      0
src/patch/lib.rs                                2      3      0
src/runtime/api/output_file_jsc.rs              3      3      0
src/runtime/bake/dev_server/mod.rs              1      1      0
(+ 8 more files)
```

</details>

<!-- robobun:evidence:end -->

---------

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
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