pyrefly icon indicating copy to clipboard operation
pyrefly copied to clipboard

fix: prevent hints from poisoning generic function inference in OR expressions

Open Imran-S-heikh opened this issue 1 month ago • 1 comments

Summary

Fixes #1635.

This PR fixes a type inference bug where generic functions (like os.getenv) returned incorrectly widened types when used on the right-hand side of an or expression.

The Issue: When reassigning a variable like config: str | None, the type checker passed the variable's current type (str | None) as a "context hint" to the right-hand side of the or. Generic functions like os.getenv(key, default) accepted this hint, widening their return type to match the hint (inferring T as None) rather than inferring the specific type from their arguments (default="string" -> T=str).

This resulted in false positive type errors (e.g., Argument 'str | None' is not assignable...) even when a valid default value was provided.

The Fix

I updated boolop in expr.rs to adjust how hints are propagated in OR expressions:

  • For Function Calls (Expr::Call): The context hint is now dropped. This forces the function to infer its return type strictly from its arguments (Inside-Out inference), preventing "poisoning" from the surrounding context.
  • For Literals/Others: The context hint is preserved. This ensures that expressions like x: List[int] = None or [] still correctly infer List[int] instead of List[Any].

Test Plan

Added a regression test test_or_generic_function_hint_poisoning_fix in operators.rs.

The test simulates the os.getenv behavior using a generic identity function and verifies that:

  1. A variable defined as str | None set to None.
  2. Reassigned via variable or identity("default").
  3. Correctly narrows to str (proving the hint str | None was ignored by the function inference).

Verification: Ran tests locally: cargo test -p pyrefly --lib test_or_generic_function_hint_poisoning_fix (Passed)

Imran-S-heikh avatar Nov 21 '25 04:11 Imran-S-heikh

@stroxler has imported this pull request. If you are a Meta employee, you can view this in D87651358.

meta-codesync[bot] avatar Nov 21 '25 17:11 meta-codesync[bot]

This pull request has been automatically marked as stale because it has not had recent activity for more than 2 weeks.

If you are still working on this this pull request, please add a comment or push new commits to keep it active. Otherwise, please unassign yourself and allow someone else to take over.

Thank you for your contributions!

github-actions[bot] avatar Dec 07 '25 00:12 github-actions[bot]