[ty] Check non-generic overload implementations (#24936)
## Summary
This PR adds support for validating that overload signatures are
compatible with that of the implementation. For now, we only support
overloads and signatures that do _not_ contain generics, since generics
introduce significant complexity (see:
https://github.com/astral-sh/ruff/pull/24937).
As a simple example, the following is now disallowed:
```python
from typing import overload
@overload
def g(x: int) -> int: ...
@overload
def g(x: str) -> str: ...
def g(x: int | str) -> int:
return 1
```
One nuance here is that we need to check the parameter and return-type
compatibilities separately. If we checked that the implementation was
assignable to the overload, it would reject valid cases like:
```python
@overload
def f(x: int) -> int: ...
@overload
def f(x: str) -> str: ...
def f(x: int | str) -> int | str:
return x
```
Since `int` is not assignable to `int | str`.
If we checked that the overload is assignable to the implementation, it
would require that the overload accepts everything the implementation
accepts, which also isn't right.
So instead, the parameters use callable assignability, but the return
type is checked directly.