refactor(semantic): classify redeclared functions without reading their AST node#22934
Closed
Boshen wants to merge 1 commit into
Closed
refactor(semantic): classify redeclared functions without reading their AST node#22934Boshen wants to merge 1 commit into
Boshen wants to merge 1 commit into
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
…ir AST node `check_function_redeclaration` distinguished a plain `FunctionDeclaration` from an `async`/generator one (Annex B.3.3) by reading the previous declaration's AST node via its stored `NodeId`. That node is a popped sibling, so the read is incompatible with making AST node storage optional. Record the `async`/generator shape at bind time instead: - `Function::bind` passes it down (it already holds the node). - New `Redeclaration` records carry it; the first declaration's value is held in build-only `SemanticBuilder` scratch (discarded after the build) and read when its record is reconstructed. - The check reads `prev.is_async_or_generator`. No `SymbolFlags` change and no `transform_checker` mask are needed: redeclarations are compared by span only and the scratch never reaches the transformer. Conformance is unchanged (zero snapshot diff).
0529374 to
8c90905
Compare
Member
|
#22972 is an alternative version of the same idea, but IMO simpler and more performant. |
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.
What
check_function_redeclaration(the Annex B.3.3 legacy duplicate-function rule) distinguished a plainFunctionDeclarationfrom anasync/generator one by reading the previous declaration's AST node through its storedNodeId:That node is a popped sibling (not an ancestor of the current node), so it's the last build-time read that would prevent making AST node storage optional.
How
The
async/generator shape is now recorded at bind time, where the node is current and free to read off theFunction(self.r#async || self.generator):Function::bindpasses it down via a newdeclare_function_symbol.Redeclarationrecord carriesis_async_or_generator. When the first declaration's record is reconstructed on the first redeclaration, its value comes from build-onlySemanticBuilderscratch (anIndexVec<SymbolId, bool>populated at symbol creation and discarded after the build) — not from the node.check_function_redeclarationreadsprev.flags.contains(Function) && !prev.is_async_or_generator— no node access.Notes
Scoping, so there's nothing to keep in sync — noSymbolFlagsbit and notransform_checkermask are needed (redeclarations are compared by span only).check_redeclaration's named-function-expression read is intentionally left on the node: that node is the enclosing function (an ancestor), so it stays reachable in parent-pointer mode.Prerequisite for making AST node storage optional (#22859).
🤖 Generated with Claude Code