[ty] Optimize inherited recursive protocol comparisons (#27922)
Generic classes inheriting recursive protocols can repeatedly expand the
same protocol interface when contextual constructor inference or
diagnostic collection binds explicitly constrained method receivers.
Programs with several inherited recursive members then become
pathologically slow.
Check finite requirements first for nominally inherited protocols, and
stop expanding recursive requirements once their constraints establish
the inherited relationship. Preserve full structural checking when it
remains necessary for erased type parameters, overridden requirements,
concrete-source inference, or diagnostic explanations. Also restrict
eager receiver-compatibility checks to overload selection, where they
actually prune candidates, so single-method binding does not recursively
re-enter the protocol.
Part of astral-sh/ty#4269.
## Ecosystem impact
Werkzeug gains two overload errors and two unused-ignore warnings
because improved contextual inference preserves the actual `sorted`
callback argument instead of widening it to `object`. This exposes its
existing `int | None` sort key; the old lambda-line ignore no longer
covers the call-level error.
## Test plan
- Protocol mdtests cover contextual constructor inference, invalid
constructor arguments, empty-iterable `Never` inference,
concrete/symbolic/unknown constrained receivers, erased type parameters
recovered structurally, and overridden recursive requirements.
- A diagnostic snapshot preserves nested protocol-member explanations
during context collection.
- A constraint-support test verifies exact type-variable identities
without treating declaration-default metadata as semantic support.
- Separate benchmarks cover recursive-protocol constructor inference and
diagnostic collection.