feat: const enum cross-module inlining support#8796
Merged
IWANABETHATGUY merged 1 commit intomainfrom Apr 15, 2026
Merged
Conversation
✅ Deploy Preview for rolldown-rs canceled.
|
c9010aa to
5fee816
Compare
3 tasks
5f0725e to
20b5750
Compare
Collaborator
Author
|
All tests passed locally; I think it is ready for review for this round. cc @IWANABETHATGUY |
graphite-app bot
pushed a commit
to oxc-project/oxc
that referenced
this pull request
Apr 13, 2026
… enum inlining (#20539) This is required in Rolldown to align with `esbuild`, which could inline a regular enum as long as all its enum members can be evaluated. See rolldown/rolldown#8796 ## Summary Depends on #20508. - Add `optimize_enums` option to `TypeScriptOptions` that treats regular enums with all-evaluable members the same as const enums: inlines member accesses and removes non-exported declarations - Regular enums are only removed when no runtime value references remain (e.g., `typeof Foo`, passing as argument) - Includes 14 conformance test fixtures covering basic, string values, binary expressions, cross-member/cross-enum references, merged enums, exported (kept), non-evaluable (kept), template literals, unary expressions, typeof/value-usage/passed-as-argument (kept), and re-exported (kept) ## Test plan - [x] 14 new conformance test fixtures under `optimize-enums/` - [x] `cargo run -p oxc_transform_conformance` passes - [x] `cargo test -p oxc_transformer` passes
Collaborator
Author
|
READY FOR REVIEW NOW |
Merging this PR will not alter performance
Comparing Footnotes
|
IWANABETHATGUY
approved these changes
Apr 15, 2026
Inline TypeScript const enum and regular enum member accesses across module boundaries so `Direction.Up` becomes the literal value at the call site, matching TypeScript's const enum semantics. - Extract enum member values in `pre_process_ecma_ast` via `SemanticBuilder::with_enum_eval(true)`, before the transformer rewrites or removes enum declarations. - Thread the name-keyed `enum_member_value_map` through `ParseToEcmaAstResult` → `EcmaView` → finalizer context. - In `ScopeHoistingFinalizer`, inline `E.M`, `ns.E.M`, and `E["M"]` accesses by looking up the enum's owning module. A bundle-level `has_enum_inlining` flag (computed once in `include_statements`) keeps the visitor's hot path free of work when no enums exist. - Skip including the enum declaration during tree-shaking when its only references are inlinable member accesses. - Enable oxc's `optimize_const_enums` and `optimize_enums` so non-exported const enum declarations are stripped and regular enum IIFEs carry `@__PURE__` for dead-code elimination.
Merged
shulaoda
added a commit
that referenced
this pull request
Apr 16, 2026
## [1.0.0-rc.16] - 2026-04-16 ### 🚀 Features - const enum cross-module inlining support (#8796) by @Dunqing - implement module tagging system for code splitting (#9045) by @hyf0 ### 🐛 Bug Fixes - rolldown_plugin_vite_manifest: handle duplicate chunk names for CSS entries (#9059) by @sapphi-red - improve error message for invalid return values in function options (#9125) by @shulaoda - await async export-star init wrappers (#9101) by @thezzisu - never panic during diagnostic emission (#9091) by @IWANABETHATGUY - include array rest pattern in binding_identifiers (#9112) by @IWANABETHATGUY - rolldown: set worker thread count with ROLLDOWN_WORKER_THREADS (#9086) by @fpotter - rolldown_plugin_lazy_compilation: escape request ID in proxy modules (#9102) by @h-a-n-a - treat namespace member access as side-effect-free (#9099) by @IWANABETHATGUY - relax overly conservative side-effect leak check in chunk optimizer (#9085) by @IWANABETHATGUY - runtime: release `cb` reference after `__commonJS` factory initialization (#9067) by @hyf0-agent - `@__NO_SIDE_EFFECTS__` wrapper should not remove dynamic imports (#9075) by @IWANABETHATGUY - rolldown_plugin_vite_import_glob: use POSIX path join/normalize for glob resolution (#9077) by @shulaoda - emit REQUIRE_TLA error when require() loads a module with top-level await (#9071) by @jaehafe - emit namespace declaration for empty modules in manual chunks (#8993) by @privatenumber - rolldown_plugin_vite_import_glob: keep common base on path segment boundary (#9070) by @shulaoda - prevent circular runtime helper imports during facade elimination (#8989) (#9057) by @IWANABETHATGUY - correct circular dependency check in facade elimination (#9047) by @h-a-n-a - docs: correct dead link in CodeSplittingGroup.tags JSDoc (#9051) by @hyf0 - emit DUPLICATE_SHEBANG warning when banner contains shebang (#9026) by @IWANABETHATGUY ### 🚜 Refactor - use semantic reference flags for member write detection (#9060) by @Dunqing - extract UsedSymbolRefs newtype wrapper (#9130) by @IWANABETHATGUY - dedupe await wrapping in export-star init emit (#9119) by @IWANABETHATGUY - calculate side-effect-free function symbols on demand (#9120) by @IWANABETHATGUY - extract duplicated top-level await handling into shared helper (#9087) by @IWANABETHATGUY - rolldown_plugin_vite_import_glob: use split_first for get_common_base (#9069) by @shulaoda - simplify ESM init deduplication with idiomatic insert check (#9044) by @IWANABETHATGUY ### 📚 Documentation - document runtime module placement strategy in code-splitting design (#9062) by @IWANABETHATGUY - clarify `options` hook behavior difference with Rollup in watch mode (#9053) by @sapphi-red - meta/design: introduce module tags (#9017) by @hyf0 ### ⚡ Performance - convert `generate_transitive_esm_init` to iterative (#9046) by @IWANABETHATGUY ### 🧪 Testing - merge strict/non_strict test variants using configVariants (#9089) by @IWANABETHATGUY ### ⚙️ Miscellaneous Tasks - disable Renovate auto-updates for oxc packages (#9129) by @IWANABETHATGUY - upgrade oxc@0.126.0 (#9127) by @Dunqing - deps: update napi to v3.8.5 (#9126) by @renovate[bot] - deps: update dependency @napi-rs/cli to v3.6.2 (#9123) by @renovate[bot] - move lazy-compilation design doc (#9117) by @h-a-n-a - deps: update dependency vite-plus to v0.1.18 (#9118) by @renovate[bot] - deps: update dependency vite-plus to v0.1.17 (#9113) by @renovate[bot] - deps: update oxc to v0.125.0 (#9094) by @renovate[bot] - deps: update dependency follow-redirects to v1.16.0 [security] (#9103) by @renovate[bot] - deps: update test262 submodule for tests (#9097) by @sapphi-red - deps: update crate-ci/typos action to v1.45.1 (#9096) by @renovate[bot] - deps: update rust crates (#9081) by @renovate[bot] - deps: update npm packages (#9080) by @renovate[bot] - remove outdated TODO in determine_module_exports_kind (#9072) by @jaehafe - rust/test: support `extendedTests: false` shorthand in test config (#9050) by @hyf0 - ci: extract shared infra-changes anchor in path filters (#9054) by @hyf0 - add docs build check to catch dead links in PRs (#9052) by @hyf0 ### ❤️ New Contributors * @thezzisu made their first contribution in [#9101](#9101) * @fpotter made their first contribution in [#9086](#9086) * @jaehafe made their first contribution in [#9071](#9071) * @privatenumber made their first contribution in [#8993](#8993) Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
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.
Summary
Enable cross-module enum inlining by consuming pre-computed enum member values from oxc_semantic.
Depends on: oxc-project/oxc#20652
closes #4342
What changed
Scopingbefore the transformer converts enums to IIFEs/placeholdersEcmaViewasenum_member_value_map(name-keyed, survives transformer rewrites)Direction.Up→0(dot notation)Direction["Up"]→0(bracket notation)ns.Direction.Up→0(chained namespace access)const enumand regularenumwhen all members have statically known valuesoptimize_const_enumsandoptimize_enumstransformer optionsArchitecture
The enum inlining pipeline follows Rolldown's existing module processing stages:
Comparison with other tools
tsc)--isolatedModules)--isolatedModules)E?.X)E["X"])ns.E.X)Performance
has_enum_inliningflag computed once during link stage, reused by generate stageTest plan
ts_enum_cross_module_inlining_access— direct + computed member access inlinedts_enum_cross_module_inlining_edge_cases— renamed re-exports, namespace re-exports, mixed value types, const vs regularts_enum_cross_module_inlining_definitions— enum definitions handled correctlyts_enum_cross_module_inlining_re_export— chainedns.Enum.Memberinlinedts_enum_cross_module_tree_shaking— dead enum declarations removedts_enum_same_module_inlining_access— same-module accesses inlinedts_const_enum_comments— const enum member accesses inlinedts_sibling_enum— merged enum declarations resolved correctlycross_module_constant_folding_*— number, string, computed property name foldingKnown limitations
E?.X) not inlined (matches esbuild behavior)/* Direction.Up */) on inlined values not yet implemented🤖 Generated with Claude Code