[ty] Fix equality-based narrowing logic for unions
This commit fixes several issues in the equality-based narrowing logic:
1. Separate union handling for narrowing target (left) vs comparison value (right):
- When the narrowing target is a union, iterate over elements and build a narrowed union
- When the comparison value is a union, check if any element could match and return Ambiguous if mixed
2. Fix handling of AlwaysUnequal for disjoint singletons:
- When comparing a singleton (like None) against a non-singleton type,
check if they're disjoint and return AlwaysUnequal if so
3. Return Some(lhs_ty) for Ambiguous in evaluate_expr_eq_or_ne:
- This ensures OR patterns in match statements don't filter out
ambiguous sub-patterns, which was causing issues with guards
Remaining known issue: The "Union with Any" test in eq.md still fails
because Any narrowing with != doesn't produce intersection types like
`(Any & ~Literal[1]) | None`. This requires further investigation.