[ty] Evaluate reachability of non-definitely-bound to Ambiguous (#19579)

## Summary

closes https://github.com/astral-sh/ty/issues/692

If the expression (or any child expressions) is not definitely bound the
reachability constraint evaluation is determined as ambiguous.

This fixes the infinite cycles panic in the following code:

```py
from typing import Literal

class Toggle:
    def __init__(self: "Toggle"):
        if not self.x:
            self.x: Literal[True] = True
```

Credit of this solution is for David.

## Test Plan

- Added a test case with too many cycle iterations panic.
- Previous tests.

---------

Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
Shaygan Hooshyari 2025-08-28 14:34:49 +02:00 committed by GitHub
parent 18eaa659c1
commit d9aaacd01f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 153 additions and 27 deletions

View file

@ -135,6 +135,10 @@ impl<'db> Place<'db> {
Place::Unbound => Place::Unbound,
}
}
pub(crate) const fn is_definitely_bound(&self) -> bool {
matches!(self, Place::Type(_, Boundness::Bound))
}
}
impl<'db> From<LookupResult<'db>> for PlaceAndQualifiers<'db> {