Skip to content

fix(flow): narrow to assigned function signatures#950

Open
lewis6991 wants to merge 1 commit intoEmmyLuaLs:mainfrom
lewis6991:fix/flow_narow_func_sig
Open

fix(flow): narrow to assigned function signatures#950
lewis6991 wants to merge 1 commit intoEmmyLuaLs:mainfrom
lewis6991:fix/flow_narow_func_sig

Conversation

@lewis6991
Copy link
Collaborator

treat signature targets as compatible when source is function-typed

@gemini-code-assist
Copy link

Summary of Changes

Hello @lewis6991, 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 addresses a type flow issue in the code analysis system by enhancing the type narrowing logic. Previously, the system did not correctly infer types when a function-typed value was assigned to a variable whose type included a function signature. The changes introduce a specific rule to ensure that such assignments lead to the correct narrowing of the variable's type to the assigned function's signature. A new test case has been added to validate this improved type inference behavior.

Highlights

  • Type Narrowing Logic Enhancement: Introduced a new rule in the type narrowing process to correctly handle assignments where the target type is a function signature (LuaType::Signature) and the source type is a function. In such cases, the target signature is now used for narrowing.
  • New Test Case for Function Assignment Narrowing: Added test_doc_function_assignment_narrowing to validate that when a variable with a union type (e.g., integer|fun():string) is assigned a function, its type is correctly narrowed to the function signature (e.g., fun()).

🧠 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.

Changelog
  • crates/emmylua_code_analysis/src/compilation/test/flow.rs
    • Added test_doc_function_assignment_narrowing to verify correct type narrowing for function assignments.
  • crates/emmylua_code_analysis/src/semantic/infer/narrow/narrow_type/mod.rs
    • Implemented a new narrowing rule for LuaType::Signature targets, allowing function-typed sources to be narrowed to the target signature.
Activity
  • No activity has been recorded for this pull request yet.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds logic to handle type narrowing for function signatures. The change itself seems correct for preserving declared signatures on assignment. However, the accompanying test case appears to exercise DocFunction types, not Signature types, and seems to require a different narrowing behavior (narrowing to the assigned function's type rather than preserving the declared type). It would be good to clarify if this is intended and if a corresponding change for DocFunction is also needed.

Comment on lines 76 to 82
LuaType::Signature(_) => {
if real_source_ref.is_function() {
return Some(target.clone());
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This change correctly preserves the declared Signature type when a function is assigned, which is great for cases where you want to maintain the API contract.

However, the new test test_doc_function_assignment_narrowing uses a DocFunction from a type annotation (--- @type integer|fun():string), not a Signature.

The test expects the type to be narrowed to the assigned function's type (fun() -> nil), which implies that for DocFunction, the narrowing logic should probably use the source type (from the RHS of the assignment). This is different from the logic for Signature where you are correctly returning target to preserve the declaration.

Could you clarify this behavior? It seems a similar change might be needed for DocFunction but with a different implementation (returning source instead of target).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In narrow_down_type, source is the antecedent/declared type and target is the assignment RHS type. For a closure RHS we infer Signature, and we intentionally return the target signature even when the antecedent is a DocFunction. That matches the runtime value (the assigned closure) and is why the new test fails without this change. So no extra DocFunction-specific branch is needed here; is_function() already covers it.

treat signature targets as compatible when source is function-typed
@lewis6991 lewis6991 force-pushed the fix/flow_narow_func_sig branch from 7298008 to e2eddfc Compare February 6, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant