Skip to content

fix(transpiler): don't inline const values into function bodies - #27160

Closed
robobun wants to merge 1 commit into
mainfrom
claude/fix-const-inlining-in-function-bodies
Closed

robobun wants to merge 1 commit into
mainfrom
claude/fix-const-inlining-in-function-bodies

Conversation

@robobun

@robobun robobun commented Feb 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fix const-inlining optimization replacing variable references with literal values inside function bodies, which changed the observable result of Function.prototype.toString()
  • Only affects the runtime transpiler (non-bundler mode); bundler path is unchanged since users explicitly opt into minification there
  • Add regression tests covering the original issue, same-scope inlining (still works), inner-function inlining (still works), toString() preservation, and let variables

Root Cause

Bun's transpiler has a const-inlining optimization that replaces references to const variables with their literal values. The const_values map was global to the parser and did not respect function scope boundaries — so const hi = "hi"; log(() => console.log(hi)) was transpiled to log(() => console.log("hi")), changing what Function.prototype.toString() returns.

When the serialized function was eval()'d in another module, the inlined literal meant the eval succeeded when it should have thrown ReferenceError, since the original variable hi doesn't exist in the eval scope.

Fix

Save and clear the const_values map when entering function/arrow bodies (in visitFunc and e_arrow), and restore it when leaving. This prevents outer-scope const values from being inlined into function bodies. Const values declared inside a function body are still inlined within that function.

The fix is gated on !p.options.bundle so the bundler path (where users explicitly opt into minification via minifySyntax) is unaffected.

Test plan

  • bun bd test test/regression/issue/12710.test.ts — 5/5 pass
  • USE_SYSTEM_BUN=1 bun test test/regression/issue/12710.test.ts — 1 fail (confirms test catches the bug)
  • bun bd test test/bundler/esbuild/default.test.ts — 150 pass (was 149 before fix due to ConstDeclRemovedIfReferencedBeforeAllUses)
  • bun bd test test/bundler/bundler_minify.test.ts — 32 pass
  • bun bd test test/bundler/bundler_string.test.ts — 59 pass
  • bun bd test test/bundler/esbuild/ts.test.ts — 57 pass

Closes #12710

🤖 Generated with Claude Code

Bun's const-inlining optimization was replacing variable references
with literal values inside function bodies, changing the observable
result of Function.prototype.toString(). This broke patterns that
rely on toString() + eval() (serialization for workers, RPC, etc.).

Only applies to the runtime transpiler (non-bundler mode) to preserve
toString() fidelity. The bundler path is unchanged since users
explicitly opt into minification there.

Closes #12710

Co-Authored-By: Claude <noreply@anthropic.com>
@robobun

robobun commented Feb 19, 2026 •

Copy link
Copy Markdown
Collaborator Author

@coderabbitai

coderabbitai Bot commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@robobun has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 5 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.


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

@claude

claude Bot commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

✅ dc3ba — Looks good!

Reviewed 3 files across src/ast/ and test/regression/: Prevents the transpiler from inlining outer-scope const values into function and arrow function bodies when not bundling, preserving Function.prototype.toString() behavior for code that relies on eval() of function source text.

@Jarred-Sumner

Copy link
Copy Markdown
Collaborator

Nooo

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.

requireing a module is sharing the current global scope with said module

2 participants