Repository navigation
fix(turbopack): classify unbound transformed references as free variables - #206
Merged
fireairforce merged 2 commits intoOct 30, 2026
Merged
Conversation
Collect surviving declarations during import analysis and infer globals from its existing usage table. Remove the two additional full-program AST traversals while preserving module-fragment classification and declaration/assignment distinctions. Co-authored-by: Sisyphus <sisyphus@opencode.ai>
fireairforce
marked this pull request as ready for review
October 30, 2026 06:07
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
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
Input transforms can introduce identifiers with the top-level syntax context even when no runtime declaration exists, or remove the TypeScript declaration that an identifier originally referred to. The analyzer treats these identifiers as local variables, so configured compile-time definitions and module provisions cannot resolve them. Classic JSX factories, including custom factories such as
h, are one example.Infer unbound references during the existing import analysis of the complete transformed program. Reuse
program_decl_usage.decl_usagesfor references, collect surviving declarations in the existing visitor, and filter after the visit so forward declarations remain bound. This removes the previous two additional whole-AST traversals and separate reference set. Handle variable declarations directly, includingvardeclarations in loop heads, and keep assignments distinct from declarations.Carry the inferred globals through the existing
force_free_valuesset. Module fragments inherit the complete program's classification. Reads and assignment tracking use the same free-variable predicate. There is no React, provider, or source-span special case, and the AST is not mutated.Pack integration and browser/Node dummy-runtime fixtures: utooland/utoo#3431 .
Validation
for (var ...)loop heads.amphtml-document,mui-sys,node-fetch, andtemplate-pages: they expectconstfor default-export temporaries although the fork's existing9c5a174ec9emitsvar. Unrelated snapshots were left unchanged.provider.hwith no source import.10fb92d1284052712a87ea78a675bf0687712cc9bf4b2c34e3b746c0357a7a1cwith Pack JS 1.5.28 and 1.5.35. Nonode_modulesfiles were changed.Performance
Compare the original behavior, the earlier two-pass implementation, and this implementation with the same
release-localoptimization and plugin feature set. Each workload uses one warmup per variant followed by 12 interleaved rounds, fresh compiler processes, persistent caching disabled, warm OS filesystem caches, no minification, and no provider. The old React-specific workaround is therefore inactive in the baseline.Build-time medians:
Paired median changes against the two-pass version are -0.93 / +1.27 / -1.98 ms, with paired median absolute deviations of 3.31 / 3.23 / 1.65 ms. Whole-process peak RSS differences are also within sampling variation. All three variants produced identical output SHA256 values in every workload. The changes are small compared with run-to-run variation; this does not establish an overall speedup or regression. These synthetic
release-localmeasurements do not measure production-release optimization, application HMR, or incremental builds.An equivalent patch is maintained against official canary
fcd3fdebcaonzoomdong/fix-synthetic-free-vars-upstream. That port is format-checked only: required nightly2026-10-06is unavailable here, and the installed older nightly fails in an unrelatedturbo-tasksdependency before reaching this crate. The compiler and execution validation above applies to this fork's pinned source/toolchain.