Describe the Bug
Consider this example:
from typing import *
def foo() -> None: pass
def condition() -> bool: ...
if condition():
x = 5
else:
pass
# if we comment this out, the uninitialized local error is detected!
foo()
print(x)
Pyrefly fails to detect the uninitialized local, because the implementation of Never and NoReturn support to fix #361 made it clear that branch termination is actually a type-level concern, but uninitialized local checks happen at binding time. As a result, the best we can do is consider branches that end in a function call "potentially terminating" and treat them as such in initialization checks.
This means we get false negatives for any code where the last statement in a branch is a call to a function that doesn't have a Never / NoReturn type.
I'm not sure it's possible to fix the bug without reworking initialization from scratch. The possible approaches I see are:
- type-level (i.e. answers-solver-time) "coloring" of names with initialization, so that the checks move to the solver. Most likely we would add an extra initialization flag to
TypeInfo if we did this, since initialization is about top-level names rather than arbitrary types.
- remove uninitialized local check entirely, and instead use it as a test bed for our first type-aware lint rule: this is actually appealing, because given our existing scope handling in bindings, initialization would be trivial to get right if we already had a typed AST - the reason it's hard now is because we're trying to do it before we have types
Sandbox Link
https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0AqADroRIzDDB0wuXAAoAlHQC0APjoA5XOhiI6xVHDjjJdAMbbMEBhG2KV6vLih7CbseghSLWa7fSKiCJ0IXT4dAC8dACsIjBQcLrBoQZGySEAxJxSAO4w5rQ0MOj8DAAWEHB0uACuDAA0jGX5NZ6eNqhQEABeMJh0ULhmnXQwlNSUnFUSDDBms5gAhOnSsooexJSsDHL4CiD1IHXQcCTkiCBZAKo2XUzSrfP%2BxqJYpjKUNKgMAProNTRsGNdnptko1HQ4AxKEF0KE6JQYAwapQ4WAhCANACgTC6MB8ABfDEiA4gMiIsBQUiEBi0KAULIABVIFKpkIwOAIBXQkDYKO%2B-kIIiyAGUYPkygwGMQ4IgAPRy8mSKmEXhsOXFOWYIZwOU%2BXn8mzaOWrSaoABuqGgqGwsG5BsoAu01WIRvQpxEZHK2mU5rGcH8kToGIAzIQAIwAJmJ6BABMOqCefoAYtAYBQ0Fg8EQyHGgA
(Only applicable for extension issues) IDE Information
No response
Describe the Bug
Consider this example:
Pyrefly fails to detect the uninitialized local, because the implementation of
NeverandNoReturnsupport to fix #361 made it clear that branch termination is actually a type-level concern, but uninitialized local checks happen at binding time. As a result, the best we can do is consider branches that end in a function call "potentially terminating" and treat them as such in initialization checks.This means we get false negatives for any code where the last statement in a branch is a call to a function that doesn't have a Never / NoReturn type.
I'm not sure it's possible to fix the bug without reworking initialization from scratch. The possible approaches I see are:
TypeInfoif we did this, since initialization is about top-level names rather than arbitrary types.Sandbox Link
https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0AqADroRIzDDB0wuXAAoAlHQC0APjoA5XOhiI6xVHDjjJdAMbbMEBhG2KV6vLih7CbseghSLWa7fSKiCJ0IXT4dAC8dACsIjBQcLrBoQZGySEAxJxSAO4w5rQ0MOj8DAAWEHB0uACuDAA0jGX5NZ6eNqhQEABeMJh0ULhmnXQwlNSUnFUSDDBms5gAhOnSsooexJSsDHL4CiD1IHXQcCTkiCBZAKo2XUzSrfP%2BxqJYpjKUNKgMAProNTRsGNdnptko1HQ4AxKEF0KE6JQYAwapQ4WAhCANACgTC6MB8ABfDEiA4gMiIsBQUiEBi0KAULIABVIFKpkIwOAIBXQkDYKO%2B-kIIiyAGUYPkygwGMQ4IgAPRy8mSKmEXhsOXFOWYIZwOU%2BXn8mzaOWrSaoABuqGgqGwsG5BsoAu01WIRvQpxEZHK2mU5rGcH8kToGIAzIQAIwAJmJ6BABMOqCefoAYtAYBQ0Fg8EQyHGgA
(Only applicable for extension issues) IDE Information
No response