Skip to content

False negatives in uninitialized local detection for branches that end in function calls (due to unknown Never/NoReturn status) #2055

@stroxler

Description

@stroxler

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

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions