subtypes: fast path for Union/Union subtype check (#14277)
Enums are exploded into Union of Literal when narrowed.
Conditional branches on enum values can result in multiple distinct
narrowing of the same enum which are later subject to subtype checks
(most notably via `is_same_type`, when exiting frame context in the binder).
Such checks would have quadratic complexity: `O(N*M)` where `N` and `M`
are the number of entries in each narrowed enum variable, and led to drastic
slowdown if any of the enums involved has a large number of values.
Implement a linear-time fast path where literals are quickly filtered, with
a fallback to the slow path for more complex values.
In our codebase there is one method with a chain of a dozen `if`
statements operating on instances of an enum with a hundreds of values.
Prior to the regression it was typechecked in less than 1s. After the regression
it takes over 13min to typecheck. This patch fully fixes the regression for us.
Fixes #13821.