Can left compare equal to right through a value domain outside nominal overlap?
(left: Type, right: Type)
| 9787 | |
| 9788 | |
| 9789 | def is_equality_ambiguous_for_narrowing(left: Type, right: Type) -> bool: |
| 9790 | """Can left compare equal to right through a value domain outside nominal overlap?""" |
| 9791 | left_info = equality_value_info(left) |
| 9792 | right_info = equality_value_info(right) |
| 9793 | |
| 9794 | if left_info.is_top or right_info.is_top: |
| 9795 | # Only open-domain enum values can make a top-like type ambiguous. |
| 9796 | # Closed domains can be narrowed to their complete known set instead. |
| 9797 | other_info = right_info if left_info.is_top else left_info |
| 9798 | return any( |
| 9799 | domain in OPEN_VALUE_EQUALITY_DOMAIN_NAMES and domain_info.enum_type_names |
| 9800 | for domain, domain_info in other_info.domains.items() |
| 9801 | ) |
| 9802 | |
| 9803 | shared_domains = left_info.domains.keys() & right_info.domains.keys() |
| 9804 | if not shared_domains: |
| 9805 | return False |
| 9806 | |
| 9807 | for domain in shared_domains: |
| 9808 | left_domain = left_info.domains[domain] |
| 9809 | right_domain = right_info.domains[domain] |
| 9810 | # Equality between two values from the same enum can still narrow by literal member. |
| 9811 | if ( |
| 9812 | left_domain.enum_type_names |
| 9813 | and left_domain.enum_type_names == right_domain.enum_type_names |
| 9814 | and left_domain.type_names == left_domain.enum_type_names |
| 9815 | and right_domain.type_names == right_domain.enum_type_names |
| 9816 | ): |
| 9817 | continue |
| 9818 | # Different domain-member types may compare equal, but nominal narrowing would |
| 9819 | # otherwise treat them as disjoint. |
| 9820 | if left_domain.type_names != right_domain.type_names: |
| 9821 | return True |
| 9822 | # Same domain-member types are only ambiguous if an enum value may compare equal to |
| 9823 | # its underlying value type. |
| 9824 | if left_domain.enum_type_names or right_domain.enum_type_names: |
| 9825 | return True |
| 9826 | |
| 9827 | return False |
| 9828 | |
| 9829 | |
| 9830 | def equality_value_info(t: Type) -> EqualityValueInfo: |
no test coverage detected
searching dependent graphs…