ast: keep a class with a static accessor initializer in place - #40887
ast: keep a class with a static accessor initializer in place#40887robobun wants to merge 3 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (5)
Included review availability: Your plan provides up to 10 included reviews per hour; 1 remains after this review. WalkthroughChangesStatic auto-accessor movement
System certificate loading
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change preserves class placement when static auto-accessor initializers may execute code; no actionable merge-blocking risk remains beyond normal checks and review. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
|
Updated 2:17 AM PT - Aug 29th, 2026
❌ @robobun, your commit 99d8634 has 1 failures in
🧪 To try this PR locally: bunx bun-pr 40887That installs a local version of the PR into your bun-40887 --bun |
bf226d8 to
99d8634
Compare
|
The retrigger commit bf226d8 accidentally carried five files from main (the root certificate loaders from #40862) that were sitting in the working tree. It is replaced by an empty commit, 99d8634. The PR is back to two files: |
|
Status: the change is ready for review. Reproduced with the test added in CI on the latest head (build 108243) is red only on lanes this change does not touch: |
Problem
bun runmoves a side-effect-free class statement to the top of the module (src/js_parser/parse/parse_entry.rs:1069, cyclic import relief).Class::can_be_moved(src/ast/g.rs:104) checks static field initializers for side effects but skips staticaccessorinitializers. Soclass C { static accessor s = f() }is hoisted andf()runs before the bindings above the class exist:ReferenceError: Cannot access 'order' before initialization.__esmwrapper, so the initializer can run at the wrong time there too.Fix
Class::can_be_movedtreatsPropertyKind::AutoAccessorlikePropertyKind::Normal. A static auto-accessor initializer that is not a literal or a function keeps the class where it was written.test/bundler/transpiler/es-decorators.test.ts(new "class statement placement" test, fails on 1.4.1 with theReferenceErrorabove). Alsoes-decorators-esbuild.test.ts,test/bundler/esbuild/ts.test.tsanddefault.test.ts.Background
accessor x = v) is a field with a generated getter and setter. Its storage is initialized like a field: during class evaluation for a static one, during construction for an instance one.__privateAdd(C, _s, v)after the class. That statement belongs to the class statement's part, so it moves with the class when the class is hoisted.Notes
Found with a differential run of the standard-decorator lowering against tsc and esbuild. The other findings of that run are covered by #40833 (field initialization order) and are reported there.
Repro on 1.4.1:
bun runthrows theReferenceErrorinsidesideEffect(the whole lowered class group runs before line 1).bun build --no-bundleoutput evaluated directly printstop,s,after class,m, because the hoist only happens in the runtime path.[stamp-90s] gate passed · iteration 0 · 2 files touched
fails on main (without fix)
passes on PR (with fix)
diff hotspot
gate history · 1 passed · 0 rejected · iteration 0
evidence per changed file