fix(flow): apply deferred narrows after antecedent resolution#989
fix(flow): apply deferred narrows after antecedent resolution#989lewis6991 wants to merge 2 commits intoEmmyLuaLs:mainfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves a critical recursion bug within the type inference system, specifically affecting correlated @return_overload narrowing. By introducing a guard mechanism, it prevents infinite loops and stack overflows during complex type analysis, significantly enhancing the stability and reliability of the semantic model generation without altering the core inference logic for valid cases. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request correctly identifies and fixes a potential stack overflow issue caused by recursive re-entry in correlated @return_overload narrowing. The approach of adding a guard to LuaInferCache is sound. The added regression test is also a great way to ensure this issue does not reappear. I have one suggestion to improve the robustness of the re-entrancy guard implementation.
crates/emmylua_code_analysis/src/semantic/infer/narrow/condition_flow/correlated_flow.rs
Outdated
Show resolved
Hide resolved
efa1423 to
81ac6be
Compare
81ac6be to
231495e
Compare
231495e to
efc8d41
Compare
6d04cf4 to
bf14cab
Compare
This comment was marked as resolved.
This comment was marked as resolved.
bf14cab to
2054627
Compare
3fa1774 to
7ad7200
Compare
When walking backward through flow, collect condition narrows as pending actions instead of applying them while recursively querying antecedent types. The eager path mixed narrowing with antecedent resolution, so stacked guards could re-enter flow inference from inside condition evaluation and build deep recursive chains across repeated truthiness, type-guard, signature-cast, and correlated return-overload checks. Resolve the antecedent type first, then apply the pending narrows in reverse order. That keeps narrowing as a post-pass over an already-resolved input, avoids re-entering the same condition chain while answering the current flow query, and lets same-variable self/member guards wait until earlier guards have narrowed the receiver enough for reliable lookup. Key the flow cache by whether condition narrowing is enabled, and separate assignment source lookup from condition application. Reuse a narrowed source only when the RHS preserves that precision; broader RHS expressions fall back to the antecedent type with condition narrowing disabled so reassignment clears stale branch narrows, while exact literals and compatible partial table/object rewrites still preserve useful narrowing. Add regression coverage for stacked guards, correlated overload joins, pcall aliases, and assign/return diagnostics.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request significantly refactors the control flow analysis to defer type narrowing. By collecting narrowing actions and applying them after resolving the antecedent type, you've addressed potential deep recursion issues and improved the correctness of type inference, especially for complex scenarios involving stacked guards and reassignments. The changes are substantial and well-supported by an impressive suite of new regression tests, which gives great confidence in the robustness of this new approach. The implementation of pending narrows and the updated caching strategy are well-executed. Overall, this is a high-quality improvement to the type system's core logic.
7ad7200 to
e102572
Compare
When walking backward through flow, collect condition narrows as pending
actions instead of applying them while recursively querying antecedent
types. The eager path mixed narrowing with antecedent resolution, so
stacked guards could re-enter flow inference from inside condition
evaluation and build deep recursive chains across repeated truthiness,
type-guard, signature-cast, and correlated return-overload checks.
Resolve the antecedent type first, then apply the pending narrows in
reverse order. That keeps narrowing as a post-pass over an
already-resolved input, avoids re-entering the same condition chain
while answering the current flow query, and lets same-variable
self/member guards wait until earlier guards have narrowed the receiver
enough for reliable lookup.
Key the flow cache by whether condition narrowing is enabled, and
separate assignment source lookup from condition application. Reuse a
narrowed source only when the RHS preserves that precision; broader RHS
expressions fall back to the antecedent type with condition narrowing
disabled so reassignment clears stale branch narrows, while exact
literals and compatible partial table/object rewrites still preserve
useful narrowing.
Add regression coverage for stacked guards, correlated overload joins,
pcall aliases, and assign/return diagnostics.
These added tests fail on
main: