Skip to content

[ty] Fix infinite hang on mutually recursive TypeAliasType definitions#23397

Merged
carljm merged 7 commits intoastral-sh:mainfrom
knutwannheden:fix/ty-recursive-typealiastype
Feb 25, 2026
Merged

[ty] Fix infinite hang on mutually recursive TypeAliasType definitions#23397
carljm merged 7 commits intoastral-sh:mainfrom
knutwannheden:fix/ty-recursive-typealiastype

Conversation

@knutwannheden
Copy link
Contributor

@knutwannheden knutwannheden commented Feb 18, 2026

Summary

Fix an infinite hang when type-checking files with mutually recursive TypeAliasType definitions created via the manual constructor:

from typing import Union
from typing_extensions import TypeAliasType

A = TypeAliasType('A', Union[str, 'B'])
B = TypeAliasType('B', list[A])

This was discovered while testing ty on pydantic's tests/test_type_alias_type.py, which contains self-referential TypeAliasType definitions such as:

JsonType = TypeAliasType(
    "JsonType",
    Union[list["JsonType"], dict[str, "JsonType"], str, int, float, bool, None]
)

Root Cause

ManualPEP695TypeAliasType was a #[salsa::interned] struct with the resolved value type as one of its fields:

#[salsa::interned]
pub struct ManualPEP695TypeAliasType<'db> {
    pub name: ast::name::Name,
    pub definition: Option>,
    pub value: Type<'db>,  // <-- causes non-convergence
}

With #[salsa::interned], all fields contribute to identity/deduplication. When Salsa detects a cycle in infer_definition_types, it re-executes the function iteratively until the result converges (stops changing). But each iteration produces a different value type as the cycle resolves, creating a new interned ID each time:

  • Iteration 1: value = Union[str, Divergent] (B not yet resolved) → interned ID X1
  • Iteration 2: value = Union[str, TypeAlias_B] (B resolved) → interned ID X2
  • Iteration 3: yet another value → yet another interned ID X3
  • ... never converges

This contrasts with PEP695TypeAliasType (the type X = ... form), which does NOT store the value in the interned struct and instead computes it lazily via a separate tracked method with its own cycle detection.

Fix

Remove the value field from ManualPEP695TypeAliasType and compute it lazily (matching the PEP695TypeAliasType pattern):

  1. types.rs: Removed value field. Added a lazy value_type() tracked method with Salsa cycle annotations that re-parses the value from the definition's AST on demand.

  2. infer/builder.rs: Created a dedicated infer_typealiastype_call method, following the same pattern used by TypeVar, ParamSpec, and NewType. This validates the arguments, constructs the ManualPEP695TypeAliasType, and defers inference of the value argument to avoid cycles. Also added an "invalid context" diagnostic when TypeAliasType is used outside a simple variable assignment.

  3. class.rs: Removed the TypeAliasType handling from KnownClass::check_call entirely, since it is now fully handled by the dedicated inference method.

Additional improvements:

  • Added validation that the first argument is a string literal matching the assignment target name (like TypeVar and NewType).
  • Corrected the error message for non-string-literal names (was referencing typing.TypeAlias, now says TypeAliasType).
  • The self-referential JSONValue test case in cycle.md now correctly resolves to the actual type instead of Divergent, since lazy evaluation means the alias is already bound by the time value_type() runs.
  • Goto-type-definition for TypeAliasType variables now correctly navigates to the assignment (previously returned "No type definitions found" because the definition was None).

Approaches Explored (and rejected)

#[salsa::tracked] with #[no_eq] on value

Changed from #[salsa::interned] to #[salsa::tracked] with #[no_eq] on the value field. Result: Still hangs — tracked struct recycling does NOT work during Salsa cycle re-iterations. Each iteration creates a new tracked struct with a fresh ID (observed IDs growing unboundedly: 9800, 9801, 9802, ...).

Register RHS as standalone expression in the semantic index builder

Registered the call expression RHS as a standalone expression so that check_call could find the definition via try_expression. Result: Breaks TypeVar, ParamSpec, NamedTuple, and NewType handling, since infer_assignment_definition_impl has a code path for standalone expressions (generic inference) and a separate code path with specialized handlers for these known classes. Registering call expressions as standalone causes all of them to take the wrong path.

Test plan

  • Added new mdtest for mutually recursive TypeAliasType definitions in pep695_type_aliases.md
  • Added mdtest for name-mismatch and invalid-context diagnostics
  • Updated cycle.md test expectation (improved from Divergent to actual resolved type)
  • Updated ty_ide snapshot for goto_type_of_bare_type_alias_type (now correctly finds the definition)
  • All 325 mdtests pass
  • All unit tests pass
  • All corpus tests pass

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Feb 18, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 18, 2026

Typing conformance results improved 🎉

The percentage of diagnostics emitted that were expected errors increased from 84.87% to 84.96%. The percentage of expected errors that received a diagnostic held steady at 75.14%.

Summary

Metric Old New Diff Outcome
True Positives 819 819 +0
False Positives 146 145 -1 ⏬ (✅)
False Negatives 271 271 +0
Total Diagnostics 965 964 -1
Precision 84.87% 84.96% +0.09% ⏫ (✅)
Recall 75.14% 75.14% +0.00%

False positives removed

Details
Location Name Message
aliases_typealiastype.py:23:5 invalid-argument-type Argument to class TypeAliasType is incorrect: Expected tuple[TypeVar | ParamSpec | typing_extensions.TypeVarTuple, ...], found tuple[TypeVar, TypeVar, ParamSpec, typing.TypeVarTuple]

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 18, 2026

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 18, 2026

mypy_primer results

Changes were detected when running on open source projects
spack (https://github.com/spack/spack)
- lib/spack/spack/detection/path.py:169:33: error[invalid-argument-type] Argument to function `dedupe_paths` is incorrect: Expected `list[str]`, found `Unknown | list[int | str | bytes | ... omitted 3 union elements]`
+ lib/spack/spack/detection/path.py:169:33: error[invalid-argument-type] Argument to function `dedupe_paths` is incorrect: Expected `list[str]`, found `Unknown | list[PathLike[str] | PathLike[bytes] | Unknown | ... omitted 3 union elements]`

pip (https://github.com/pypa/pip)
- src/pip/_internal/req/req_uninstall.py:132:42: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Sized | Unknown`
+ src/pip/_internal/req/req_uninstall.py:132:42: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Unknown | Sized`
- src/pip/_internal/req/req_uninstall.py:133:40: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Sized | Unknown`
+ src/pip/_internal/req/req_uninstall.py:133:40: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Unknown | Sized`
- src/pip/_internal/req/req_uninstall.py:139:27: error[unsupported-operator] Operator `+` is not supported between objects of type `Sized | Unknown` and `LiteralString`
+ src/pip/_internal/req/req_uninstall.py:139:27: error[unsupported-operator] Operator `+` is not supported between objects of type `Unknown | Sized` and `LiteralString`

pylint (https://github.com/pycqa/pylint)
- pylint/checkers/refactoring/implicit_booleaness_checker.py:219:24: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `Unknown | str`
+ pylint/checkers/refactoring/implicit_booleaness_checker.py:219:24: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `str | Unknown`
- pylint/checkers/refactoring/implicit_booleaness_checker.py:219:62: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `Unknown | str`
+ pylint/checkers/refactoring/implicit_booleaness_checker.py:219:62: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `str | Unknown`
- pylint/checkers/refactoring/implicit_booleaness_checker.py:222:27: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `(Unknown & ~None) | str`
+ pylint/checkers/refactoring/implicit_booleaness_checker.py:222:27: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `str | (Unknown & ~None)`
- pylint/checkers/refactoring/implicit_booleaness_checker.py:236:29: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `Unknown | str`
+ pylint/checkers/refactoring/implicit_booleaness_checker.py:236:29: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `str | Unknown`
- pylint/checkers/refactoring/implicit_booleaness_checker.py:239:29: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `Unknown | str`
+ pylint/checkers/refactoring/implicit_booleaness_checker.py:239:29: error[unresolved-attribute] Attribute `as_string` is not defined on `str` in union `str | Unknown`

sockeye (https://github.com/awslabs/sockeye)
- sockeye/output_handler.py:254:80: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[Unknown | list[str]]`, found `list[list[str]] | None`
+ sockeye/output_handler.py:254:80: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[list[str] | Unknown]`, found `list[list[str]] | None`

porcupine (https://github.com/Akuli/porcupine)
+ porcupine/pluginmanager.py:133:49: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[Never]`, found `Unknown | str`
- Found 24 diagnostics
+ Found 25 diagnostics

artigraph (https://github.com/artigraph/artigraph)
- tests/arti/types/test_types.py:100:51: error[invalid-argument-type] Argument is incorrect: Expected `frozenset[Any]`, found `frozenset[float | Unknown | int] | list[Unknown | int | float] | tuple[float | Unknown | int, ...]`
+ tests/arti/types/test_types.py:100:51: error[invalid-argument-type] Argument is incorrect: Expected `frozenset[Any]`, found `frozenset[float | Unknown | int] | list[int | Unknown | float] | tuple[float | Unknown | int, ...]`

openlibrary (https://github.com/internetarchive/openlibrary)
- openlibrary/catalog/utils/__init__.py:132:17: error[unresolved-attribute] Attribute `search` is not defined on `str` in union `str | Unknown`
+ openlibrary/catalog/utils/__init__.py:132:17: error[unresolved-attribute] Attribute `search` is not defined on `str` in union `Unknown | str`

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/deployments/runner.py:1017:70: error[unresolved-attribute] Attribute `__name__` is not defined on `((...) -> Any) & ((*args: object, **kwargs: object) -> object)` in union `Unknown | (((...) -> Any) & ((*args: object, **kwargs: object) -> object))`
+ src/prefect/deployments/runner.py:1017:70: error[unresolved-attribute] Attribute `__name__` is not defined on `(...) -> Any` in union `Unknown | ((...) -> Any)`
+ src/prefect/flow_engine.py:1004:32: error[invalid-await] `Unknown | R@FlowRunEngine | Coroutine[Any, Any, R@FlowRunEngine]` is not awaitable
+ src/prefect/flow_engine.py:1610:24: error[invalid-await] `Unknown | R@AsyncFlowRunEngine | Coroutine[Any, Any, R@AsyncFlowRunEngine]` is not awaitable
- src/prefect/flows.py:286:34: error[unresolved-attribute] Object of type `((**P@Flow) -> R@Flow) & ((*args: object, **kwargs: object) -> object)` has no attribute `__name__`
+ src/prefect/flows.py:286:34: error[unresolved-attribute] Object of type `(**P@Flow) -> R@Flow` has no attribute `__name__`
- src/prefect/flows.py:404:68: error[unresolved-attribute] Object of type `((**P@Flow) -> R@Flow) & ((*args: object, **kwargs: object) -> object)` has no attribute `__name__`
+ src/prefect/flows.py:404:68: error[unresolved-attribute] Object of type `(**P@Flow) -> R@Flow` has no attribute `__name__`
- src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `Unknown | Coroutine[Any, Any, Unknown]`
+ src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler] | Coroutine[Any, Any, T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]]`
- src/prefect/utilities/asyncutils.py:198:16: error[invalid-return-type] Return type does not match returned value: expected `R@run_coro_as_sync | None`, found `CoroutineType[Any, Any, R@run_coro_as_sync | None] | R@run_coro_as_sync | None`
- src/prefect/utilities/asyncutils.py:207:20: error[invalid-return-type] Return type does not match returned value: expected `R@run_coro_as_sync | None`, found `CoroutineType[Any, Any, R@run_coro_as_sync | None] | R@run_coro_as_sync | None`

ibis (https://github.com/ibis-project/ibis)
- ibis/selectors.py:333:16: error[invalid-return-type] Return type does not match returned value: expected `frozenset[str]`, found `frozenset[str | Unknown | Buffer]`
+ ibis/selectors.py:333:16: error[invalid-return-type] Return type does not match returned value: expected `frozenset[str]`, found `frozenset[str | Buffer | Unknown]`

bokeh (https://github.com/bokeh/bokeh)
- src/bokeh/layouts.py:670:21: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[L@_parse_children_arg]`, found `tuple[L@_parse_children_arg | list[L@_parse_children_arg], ...]`
+ src/bokeh/layouts.py:670:16: error[invalid-return-type] Return type does not match returned value: expected `list[L@_parse_children_arg]`, found `list[L@_parse_children_arg | list[L@_parse_children_arg]]`

static-frame (https://github.com/static-frame/static-frame)
- static_frame/test/unit/test_bus.py:2137:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `ndarray[Any, Any] | @Todo | Series[Any, Any]`
+ static_frame/test/unit/test_bus.py:2137:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `@Todo | Series[Any, Any] | ndarray[Any, Any]`
- static_frame/test/unit/test_bus.py:2138:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `ndarray[Any, Any] | @Todo | Series[Any, Any]`
+ static_frame/test/unit/test_bus.py:2138:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `@Todo | Series[Any, Any] | ndarray[Any, Any]`
- static_frame/test/unit/test_bus.py:2166:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `ndarray[Any, Any] | @Todo | Series[Any, Any]`
+ static_frame/test/unit/test_bus.py:2166:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `@Todo | Series[Any, Any] | ndarray[Any, Any]`
- static_frame/test/unit/test_bus.py:2167:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `ndarray[Any, Any] | @Todo | Series[Any, Any]`
+ static_frame/test/unit/test_bus.py:2167:26: error[unresolved-attribute] Attribute `to_pairs` is not defined on `ndarray[Any, Any]` in union `@Todo | Series[Any, Any] | ndarray[Any, Any]`

pandas (https://github.com/pandas-dev/pandas)
- pandas/core/methods/describe.py:215:21: error[not-iterable] Object of type `Unknown | Sized` may not be iterable
+ pandas/core/methods/describe.py:215:21: error[not-iterable] Object of type `Sized | Unknown` may not be iterable

sympy (https://github.com/sympy/sympy)
+ sympy/algebras/tests/test_quaternion.py:75:10: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/algebras/tests/test_quaternion.py:75:10: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/algebras/tests/test_quaternion.py:422:33: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/codegen/tests/test_matrix_nodes.py:27:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/geometry/point.py:1295:25: error[unresolved-attribute] Attribute `tolist` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/geometry/point.py:1295:25: error[unresolved-attribute] Attribute `tolist` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/geometry/tests/test_util.py:128:55: error[invalid-argument-type] Argument to function `subsets` is incorrect: Expected `Sequence[Unknown]`, found `set[Point2D | Unknown]`
+ sympy/geometry/tests/test_util.py:128:55: error[invalid-argument-type] Argument to function `subsets` is incorrect: Expected `Sequence[Unknown]`, found `set[Unknown | Point2D]`
- sympy/integrals/tests/test_heurisch.py:390:26: error[not-subscriptable] Cannot subscript object of type `Expr` with no `__getitem__` method
+ sympy/integrals/tests/test_heurisch.py:389:17: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/decompositions.py:1321:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/decompositions.py:1336:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/decompositions.py:1321:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/decompositions.py:1334:13: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase`
+ sympy/matrices/decompositions.py:1336:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/decompositions.py:1348:13: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase`
- sympy/matrices/decompositions.py:1350:12: error[invalid-return-type] Return type does not match returned value: expected `tuple[Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition]`, found `tuple[MatrixBase | Expr | Unknown, MatrixBase, MatrixBase | Expr | Unknown]`
+ sympy/matrices/decompositions.py:1350:12: error[invalid-return-type] Return type does not match returned value: expected `tuple[Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition]`, found `tuple[Unknown | MatrixBase, MatrixBase, MatrixBase | Unknown]`
+ sympy/matrices/eigen.py:328:22: error[invalid-argument-type] Argument to bound method `_as_type` is incorrect: Expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown`
+ sympy/matrices/eigen.py:1202:37: error[unresolved-attribute] Object of type `T2'return@call_highest_priority | T1'return@call_highest_priority` has no attribute `pow`
- sympy/matrices/expressions/hadamard.py:81:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Any | Basic | int | float | complex`
+ sympy/matrices/expressions/hadamard.py:81:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Basic | int | float | complex | Any`
- sympy/matrices/expressions/kronecker.py:109:16: error[unresolved-attribute] Attribute `is_Identity` is not defined on `Basic`, `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
+ sympy/matrices/expressions/kronecker.py:109:16: error[unresolved-attribute] Attribute `is_Identity` is not defined on `Basic`, `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/matrices/expressions/kronecker.py:110:33: error[unresolved-attribute] Attribute `rows` is not defined on `Basic`, `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
+ sympy/matrices/expressions/kronecker.py:110:33: error[unresolved-attribute] Attribute `rows` is not defined on `Basic`, `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
+ sympy/matrices/expressions/tests/test_blockmatrix.py:235:13: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/expressions/tests/test_blockmatrix.py:235:33: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/expressions/tests/test_blockmatrix.py:235:53: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/expressions/tests/test_blockmatrix.py:459:12: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/expressions/tests/test_derivatives.py:551:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/expressions/tests/test_matadd.py:36:12: error[unsupported-operator] Operator `+` is not supported between objects of type `MatrixBase` and `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matmul.py:158:68: error[unresolved-attribute] Attribute `as_explicit` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/expressions/tests/test_matmul.py:158:68: error[unresolved-attribute] Attribute `as_explicit` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/expressions/tests/test_matpow.py:123:46: error[unsupported-operator] Operator `**` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Literal[2]`
+ sympy/matrices/expressions/tests/test_matpow.py:124:47: error[unsupported-operator] Operator `+` is not supported between two objects of type `ImmutableDenseMatrix`
- sympy/matrices/expressions/tests/test_permutation.py:27:12: error[unresolved-attribute] Attribute `as_explicit` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/expressions/tests/test_permutation.py:27:12: error[unresolved-attribute] Attribute `as_explicit` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/inverse.py:384:11: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase`
+ sympy/matrices/inverse.py:392:11: error[unsupported-operator] Unary operator `-` is not supported for object of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/inverse.py:393:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase | Expr`
+ sympy/matrices/inverse.py:393:22: error[unsupported-operator] Unary operator `-` is not supported for object of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/matrixbase.py:979:18: error[unsupported-operator] Operator `+` is not supported between two objects of type `Self@_eval_wilkinson`
+ sympy/matrices/matrixbase.py:2955:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T2'return@call_highest_priority` and `Self@_eval_pow_by_cayley`
+ sympy/matrices/matrixbase.py:2955:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T1'return@call_highest_priority` and `Self@_eval_pow_by_cayley`
+ sympy/matrices/matrixbase.py:2957:16: error[invalid-return-type] Return type does not match returned value: expected `Self@_eval_pow_by_cayley`, found `Self@_eval_pow_by_cayley | T2'return@call_highest_priority | T1'return@call_highest_priority | Unknown`
- sympy/matrices/matrixbase.py:3046:5: error[invalid-argument-type] Argument is incorrect: Expected `(MatrixBase, MatrixBase | Expr, /) -> MatrixBase | Expr`, found `Overload[[Self](self, other: Self) -> Self, (self, other: MatrixBase) -> MatrixBase, (self, other: Expr) -> MatrixBase]`
+ sympy/matrices/matrixbase.py:3046:5: error[invalid-argument-type] Argument is incorrect: Expected `(T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr, T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr, /) -> T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`, found `Overload[[Self](self, other: Self) -> Self, (self, other: MatrixBase) -> MatrixBase, (self, other: Expr) -> MatrixBase]`
+ sympy/matrices/matrixbase.py:3256:16: error[invalid-return-type] Return type does not match returned value: expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority`
+ sympy/matrices/matrixbase.py:3256:29: error[invalid-argument-type] Argument is incorrect: Expected `T2'return@call_highest_priority | T1'return@call_highest_priority`, found `MatrixBase`
+ sympy/matrices/matrixbase.py:3310:16: error[unsupported-operator] Operator `+` is not supported between two objects of type `MatrixBase`
+ sympy/matrices/matrixbase.py:3314:16: error[invalid-return-type] Return type does not match returned value: expected `Tmat@__sub__`, found `MatrixBase`
+ sympy/matrices/matrixbase.py:3944:39: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/matrixbase.py:3944:39: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/matrixbase.py:4386:16: error[unsupported-operator] Operator `+` is not supported between two objects of type `Self@add`
- sympy/matrices/matrixbase.py:4640:16: error[invalid-return-type] Return type does not match returned value: expected `Self@D`, found `MatrixBase | Expr`
+ sympy/matrices/matrixbase.py:4640:16: error[invalid-return-type] Return type does not match returned value: expected `Self@D`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/matrixbase.py:4748:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/matrixbase.py:4748:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/matrixbase.py:4922:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T2'return@call_highest_priority` and `Self@analytic_func`
+ sympy/matrices/matrixbase.py:4922:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T1'return@call_highest_priority` and `Self@analytic_func`
+ sympy/matrices/matrixbase.py:4923:16: error[invalid-return-type] Return type does not match returned value: expected `Self@analytic_func`, found `Self@analytic_func | T2'return@call_highest_priority | T1'return@call_highest_priority | Unknown`
- sympy/matrices/matrixbase.py:5073:28: error[invalid-argument-type] Argument is incorrect: Expected `Self@log`, found `MatrixBase | Expr | Unknown`
- sympy/matrices/matrixbase.py:5078:16: error[invalid-return-type] Return type does not match returned value: expected `Self@log`, found `MatrixBase | Expr | Unknown`
+ sympy/matrices/matrixbase.py:5073:28: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Self@log`
+ sympy/matrices/matrixbase.py:5076:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Self@log`
+ sympy/matrices/repmatrix.py:321:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `Self@_eval_is_symmetric`
+ sympy/matrices/solvers.py:637:27: error[invalid-argument-type] Argument to bound method `vstack` is incorrect: Argument type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown` does not satisfy upper bound `MatrixBase` of type variable `Self`
+ sympy/matrices/solvers.py:637:27: error[invalid-argument-type] Argument to bound method `vstack` is incorrect: Expected `Tmat@_gauss_jordan_solve`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown`
+ sympy/matrices/solvers.py:741:12: error[invalid-return-type] Return type does not match returned value: expected `Tmat@_pinv_solve`, found `T2'return@call_highest_priority | T1'return@call_highest_priority`
- sympy/matrices/solvers.py:976:16: error[unresolved-attribute] Attribute `solve` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/solvers.py:976:16: error[unresolved-attribute] Attribute `solve` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Argument type `MatrixBase | Expr` does not satisfy upper bound `MatrixBase` of type variable `Self`
+ sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Argument type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` does not satisfy upper bound `MatrixBase` of type variable `Self`
- sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Expected `MatrixBase`, found `MatrixBase | Expr`
+ sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/sparse.py:417:16: error[unresolved-attribute] Attribute `inv` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/sparse.py:417:16: error[unresolved-attribute] Attribute `inv` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_commonmatrix.py:1249:31: error[unsupported-operator] Operator `+` is not supported between objects of type `MutableDenseMatrix` and `ImmutableDenseNDimArray`
- sympy/matrices/tests/test_decompositions.py:23:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:23:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:32:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:32:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:42:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:42:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:51:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:51:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:57:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:57:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:77:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:84:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:90:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:103:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:110:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:123:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:131:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:131:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:288:10: error[unresolved-attribute] Attribute `applyfunc` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:288:10: error[unresolved-attribute] Attribute `applyfunc` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:393:16: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_decompositions.py:394:16: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:290:13: error[unsupported-operator] Operator `-` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:345:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:348:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:355:23: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:393:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:394:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:395:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:395:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:396:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:396:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:439:13: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:439:22: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:451:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:451:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:464:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:464:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:475:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:475:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:488:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:488:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:477:12: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_eigen.py:492:12: error[unresolved-attribute] Attribute `applyfunc` is not defined on `Expr` in union `MatrixBase | Expr | Unknown`
+ sympy/matrices/tests/test_eigen.py:257:16: error[unresolved-attribute] Attribute `n` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_eigen.py:306:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:307:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:322:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:323:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:364:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:365:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:380:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:381:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:405:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:477:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:492:13: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_eigen.py:793:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_immutable.py:105:23: error[unsupported-operator] Operator `+` is not supported between two objects of type `ImmutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:121:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:123:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:141:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:201:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:201:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:202:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:202:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:203:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:203:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:204:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:204:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:205:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:205:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:206:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:206:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:213:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:213:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:214:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:214:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:215:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:215:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:216:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:216:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:217:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:217:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:218:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrices.py:218:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:221:40: error[invalid-argument-type] Argument to bound method `multiply_elementwise` is incorrect: Expected `MatrixBase`, found `MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:221:40: error[invalid-argument-type] Argument to bound method `multiply_elementwise` is incorrect: Expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:394:16: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:1739:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_matrices.py:1581:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:1587:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:1594:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:1599:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:1607:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:1616:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:1739:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2179:22: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2207:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2557:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2680:16: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_matrices.py:2681:16: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_matrices.py:2680:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2681:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2682:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:2682:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrices.py:2683:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:2683:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrices.py:2728:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:2728:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrices.py:2746:25: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:2746:25: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:2908:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2921:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2936:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2937:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:2948:14: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:3055:33: error[unresolved-attribute] Attribute `analytic_func` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:3055:33: error[unresolved-attribute] Attribute `analytic_func` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrices.py:3071:60: error[unresolved-attribute] Attribute `exp` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:3071:60: error[unresolved-attribute] Attribute `exp` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:3471:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:3477:12: error[unresolved-attribute] Attribute `rank` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown`
+ sympy/matrices/tests/test_matrices.py:3478:13: error[unsupported-operator] Operator `**` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown` and `Literal[2]`
+ sympy/matrices/tests/test_matrices.py:3479:13: error[unsupported-operator] Operator `**` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown` and `Literal[3]`
+ sympy/matrices/tests/test_matrixbase.py:491:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:493:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:544:12: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:823:31: error[unsupported-operator] Operator `+` is not supported between objects of type `MutableDenseMatrix` and `ImmutableDenseNDimArray`
+ sympy/matrices/tests/test_matrixbase.py:876:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:878:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:900:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:963:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:963:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:964:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:964:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:965:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:965:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:966:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:966:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:967:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:967:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:968:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:968:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
+ sympy/matrices/tests/test_matrixbase.py:1148:16: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:2497:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_matrixbase.py:2339:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2345:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2352:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2357:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2365:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2374:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2497:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2931:22: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:2959:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:3288:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3384:16: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_matrixbase.py:3385:16: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_matrixbase.py:3384:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:3385:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3386:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrixbase.py:3386:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrixbase.py:3387:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrixbase.py:3387:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrixbase.py:3432:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrixbase.py:3432:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrixbase.py:3450:25: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrixbase.py:3450:25: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrixbase.py:3610:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:3624:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:3639:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:3640:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrixbase.py:3652:14: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3768:33: error[unresolved-attribute] Attribute `analytic_func` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_matrixbase.py:3768:33: error[unresolved-attribute] Attribute `analytic_func` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_matrixbase.py:3784:60: error[unresolved-attribute] Attribute `exp` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_matrixbase.py:3784:60: error[unresolved-attribute] Attribute `exp` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_pri

... (truncated 296 lines) ...

@knutwannheden knutwannheden force-pushed the fix/ty-recursive-typealiastype branch from 75a22ce to 5d2914e Compare February 18, 2026 18:30
## Problem

ty hangs indefinitely when type-checking files with mutually recursive
`TypeAliasType` definitions created via the manual constructor:

```python
A = TypeAliasType('A', Union[str, 'B'])
B = TypeAliasType('B', list[A])
```

This was discovered while testing ty on pydantic's `test_type_alias_type.py`.

## Root Cause

`ManualPEP695TypeAliasType` was a `#[salsa::interned]` struct with the
resolved value type as one of its fields:

```rust
#[salsa::interned]
pub struct ManualPEP695TypeAliasType<'db> {
    pub name: ast::name::Name,
    pub definition: Option<Definition<'db>>,
    pub value: Type<'db>,  // <-- causes non-convergence
}
```

With `#[salsa::interned]`, ALL fields contribute to identity. When Salsa
detects a cycle in `infer_definition_types`, it re-executes the function
iteratively until the result converges (stops changing). But each iteration
produces a different `value` type as the cycle resolves, creating a new
interned ID each time:

  - Iteration 1: value=`Union[str, Divergent]` → interned ID X1
  - Iteration 2: value=`Union[str, TypeAlias_B]` → interned ID X2
  - Iteration 3: yet another value → interned ID X3
  - ... never converges

This contrasts with `PEP695TypeAliasType` (the `type X = ...` form), which
does NOT store the value in the interned struct and instead computes it
lazily via a separate tracked method with its own cycle detection.

## Approaches Explored

### Approach 1: `#[salsa::tracked]` with `#[no_eq]` on value

Changed from `#[salsa::interned]` to `#[salsa::tracked]` with `#[no_eq]`
on the value field, so that value changes don't affect the struct's identity.

**Result**: Still hangs. Tracked struct recycling does NOT work during Salsa
cycle re-iterations — each iteration creates a new tracked struct with a
fresh ID (observed IDs growing unboundedly: 9800, 9801, 9802, ...).
Additionally, `normalized_impl` and `recursive_type_normalized_impl` called
`Self::new()` which created additional tracked structs. Even after fixing
those to return `self`, the fundamental ID proliferation remained.

### Approach 2: Remove value from interned struct + register RHS as standalone expression

Removed the `value` field from the interned struct and computed it lazily
via a tracked `value_type()` method (mirroring PEP695TypeAliasType). But
the lazy method needs the `Definition` to find the AST node, and for simple
assignments (`X = expr`), the semantic index builder does NOT register the
RHS as a standalone expression — so `try_expression()` returns None and the
definition is unavailable.

Attempted to fix this by registering the RHS call expression as standalone
in the semantic index builder.

**Result**: Breaks TypeVar, ParamSpec, NamedTuple, and NewType handling.
`infer_assignment_definition_impl` has two code paths: if a standalone
expression exists, it uses generic `infer_standalone_expression_impl`; if
not, it checks for TypeVar/ParamSpec/NamedTuple/NewType/etc. and uses
specialized handlers. Registering call expressions as standalone causes ALL
of these to take the wrong path.

### Approach 3 (final): Remove value + thread definition via infer_assignment_definition_impl

Same lazy value computation as Approach 2, but instead of modifying the
semantic index, thread the definition through the existing type inference
path. In `infer_assignment_definition_impl`, `TypeAliasType` calls already
pass through the `else if let ast::Expr::Call` branch where the `definition`
is in scope. Added a `KnownClass::TypeAliasType` match arm that:
1. Does normal call inference (which creates a ManualPEP695TypeAliasType
   with definition=None via check_call)
2. Patches up the result with the definition that's available in scope

This is the same pattern used for TypeVar, ParamSpec, NewType, and
builtins.type — all have special handling in this match.

## Changes

- **types.rs**: Removed `value` field from `ManualPEP695TypeAliasType`.
  Added lazy `value_type()` tracked method with Salsa cycle annotations.
  `normalized_impl` and `recursive_type_normalized_impl` return `self`
  since the interned identity no longer depends on the value.

- **class.rs**: Updated `check_call` to not pass `value` to `new()`.

- **infer/builder.rs**: Added `KnownClass::TypeAliasType` match arm in
  `infer_assignment_definition_impl` to supply the definition that
  `check_call` can't find via `try_expression` for simple assignments.

- **arguments.rs**: Removed `expand_pep695_type_alias` unit test (can't
  construct ManualPEP695TypeAliasType with a value in unit tests anymore;
  functionality is covered by mdtests).

- **pep695_type_aliases.md**: Added mdtest for mutually recursive
  TypeAliasType definitions.

- **cycle.md**: Updated test expectation for self-referential JSONValue
  TypeAliasType — now correctly resolves to the actual type instead of
  Divergent, since lazy evaluation means the alias is already bound by
  the time value_type() runs.
@knutwannheden
Copy link
Contributor Author

To me the mypy_primer results look like in some cases there were invalid-await that were probably due to some type alias getting resolved to Unknown. Now instead there are other more accurate reported type errors, that were masked before.

@AlexWaygood
Copy link
Member

To me the mypy_primer results look like in some cases there were invalid-await that were probably due to some type alias getting resolved to Unknown. Now instead there are other more accurate reported type errors, that were masked before.

ah, no, we're just quite nondeterministic right now unfortunately. Those are known flakes. Sorry for the false alarm.

knutwannheden added a commit to openrewrite/ruff that referenced this pull request Feb 19, 2026
@carljm carljm closed this Feb 24, 2026
@carljm carljm reopened this Feb 24, 2026
@carljm carljm assigned carljm and unassigned MichaReiser Feb 24, 2026
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this fix! I think this is on the right track, but should go even further towards using the same pattern as e.g. TypeVar and NewType calls.

Replace the hybrid approach (check_call + builder patch) with a
dedicated `infer_typealiastype_call` method, following the pattern
used by TypeVar and NewType. This removes the TypeAliasType branch
from `KnownClass::check_call` and consolidates all logic into the
builder.

Also adds validation that the name argument matches the assignment
target, and emits `invalid-type-alias-type` when TypeAliasType is
used outside a simple variable assignment.
@AlexWaygood AlexWaygood removed their request for review February 25, 2026 08:21
@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 25, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
unsupported-operator 4 0 0
invalid-argument-type 2 0 0
unresolved-attribute 2 0 0
Total 8 0 0

Full report with detailed diff (timing results)

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you! I pushed a few minor cleanups (definition no longer needs to be Option, and we can further remove/simplify some other methods now) as well as one fix (we broke the binding context for typevars in generic manual aliases).

@carljm carljm merged commit 093a88f into astral-sh:main Feb 25, 2026
50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ecosystem-analyzer ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants