mirror of
https://github.com/astral-sh/ruff
synced 2026-01-21 13:30:49 -05:00
This fixes issue #2470 where recursive type aliases like `type RecursiveT = int | tuple[RecursiveT, ...]` caused a stack overflow when used in return type checking with constructors like `list()`. The fix moves all type mapping processing for `UniqueSpecialization` (and other non-EagerExpansion mappings) inside the `visitor.visit()` closure. This ensures that if we encounter the same TypeAlias recursively during type mapping, the cycle detector will properly detect it and return the fallback value instead of recursing infinitely. The key insight is that the previous code called `apply_function_specialization` followed by another `apply_type_mapping_impl` AFTER the visitor closure returned. At that point, the TypeAlias was no longer in the visitor's `seen` set, so recursive references would not be detected as cycles.