@@ -1053,31 +1053,23 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
10531053 && rhs_ty. is_singleton ( self . db )
10541054 {
10551055 let is_positive_check = is_positive == ( ops[ 0 ] == ast:: CmpOp :: Is ) ;
1056- let union_elements = union. elements ( self . db ) ;
1057- let filtered: Vec < _ > = union_elements
1058- . iter ( )
1059- . filter ( |elem| {
1060- elem. as_nominal_instance ( )
1061- . and_then ( |inst| inst. tuple_spec ( self . db ) )
1062- . and_then ( |spec| spec. py_index ( self . db , index) . ok ( ) )
1063- . is_none_or ( |el_ty| {
1064- if is_positive_check {
1065- // `is X` context: keep tuples where element could be X
1066- !el_ty. is_disjoint_from ( self . db , rhs_ty)
1067- } else {
1068- // `is not X` context: keep tuples where element is not always X
1069- !el_ty. is_subtype_of ( self . db , rhs_ty)
1070- }
1071- } )
1072- } )
1073- . copied ( )
1074- . collect ( ) ;
1075- if filtered. len ( ) < union_elements. len ( ) {
1056+ let filtered = union. filter ( self . db , |elem| {
1057+ elem. as_nominal_instance ( )
1058+ . and_then ( |inst| inst. tuple_spec ( self . db ) )
1059+ . and_then ( |spec| spec. py_index ( self . db , index) . ok ( ) )
1060+ . is_none_or ( |el_ty| {
1061+ if is_positive_check {
1062+ // `is X` context: keep tuples where element could be X
1063+ !el_ty. is_disjoint_from ( self . db , rhs_ty)
1064+ } else {
1065+ // `is not X` context: keep tuples where element is not always X
1066+ !el_ty. is_subtype_of ( self . db , rhs_ty)
1067+ }
1068+ } )
1069+ } ) ;
1070+ if filtered != Type :: Union ( union) {
10761071 let place = self . expect_place ( & subscript_place_expr) ;
1077- constraints. insert (
1078- place,
1079- NarrowingConstraint :: replacement ( UnionType :: from_elements ( self . db , filtered) ) ,
1080- ) ;
1072+ constraints. insert ( place, NarrowingConstraint :: replacement ( filtered) ) ;
10811073 }
10821074 }
10831075
@@ -1766,33 +1758,25 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
17661758 }
17671759
17681760 // Filter the union based on whether each tuple element at the index could match the rhs.
1769- let union_elements = union. elements ( self . db ) ;
1770- let filtered: Vec < _ > = union_elements
1771- . iter ( )
1772- . filter ( |elem| {
1773- elem. as_nominal_instance ( )
1774- . and_then ( |inst| inst. tuple_spec ( self . db ) )
1775- . and_then ( |spec| spec. py_index ( self . db , index) . ok ( ) )
1776- . is_none_or ( |el_ty| {
1777- if constrain_with_equality {
1778- // Keep tuples where element could be equal to rhs.
1779- !el_ty. is_disjoint_from ( self . db , rhs_type)
1780- } else {
1781- // Keep tuples where element is not always equal to rhs.
1782- !el_ty. is_subtype_of ( self . db , rhs_type)
1783- }
1784- } )
1785- } )
1786- . copied ( )
1787- . collect ( ) ;
1761+ let filtered = union. filter ( self . db , |elem| {
1762+ elem. as_nominal_instance ( )
1763+ . and_then ( |inst| inst. tuple_spec ( self . db ) )
1764+ . and_then ( |spec| spec. py_index ( self . db , index) . ok ( ) )
1765+ . is_none_or ( |el_ty| {
1766+ if constrain_with_equality {
1767+ // Keep tuples where element could be equal to rhs.
1768+ !el_ty. is_disjoint_from ( self . db , rhs_type)
1769+ } else {
1770+ // Keep tuples where element is not always equal to rhs.
1771+ !el_ty. is_subtype_of ( self . db , rhs_type)
1772+ }
1773+ } )
1774+ } ) ;
17881775
17891776 // Only create a constraint if we actually narrowed something.
1790- if filtered. len ( ) < union_elements . len ( ) {
1777+ if filtered != rhs_type {
17911778 let place = self . expect_place ( & subscript_place_expr) ;
1792- Some ( (
1793- place,
1794- NarrowingConstraint :: replacement ( UnionType :: from_elements ( self . db , filtered) ) ,
1795- ) )
1779+ Some ( ( place, NarrowingConstraint :: replacement ( filtered) ) )
17961780 } else {
17971781 None
17981782 }
0 commit comments