@@ -81,6 +81,30 @@ def meet_types(s: Type, t: Type) -> ProperType:
8181 t = get_proper_type (t )
8282
8383 if isinstance (s , Instance ) and isinstance (t , Instance ) and s .type == t .type :
84+ # special casing for dealing with last known values
85+ lkv : LiteralType | None
86+
87+ if s .last_known_value is None :
88+ lkv = t .last_known_value
89+ elif t .last_known_value is None :
90+ lkv = s .last_known_value
91+ else :
92+ lkv_meet = meet_types (s .last_known_value , t .last_known_value )
93+ if isinstance (lkv_meet , UninhabitedType ):
94+ lkv = None
95+ elif isinstance (lkv_meet , LiteralType ):
96+ lkv = lkv_meet
97+ else :
98+ msg = (
99+ f"Unexpected result: "
100+ f"meet of { s .last_known_value = !s} and { t .last_known_value = !s} "
101+ f"resulted in { lkv_meet !s} "
102+ )
103+ raise ValueError (msg )
104+
105+ t = t .copy_modified (last_known_value = lkv )
106+ s = s .copy_modified (last_known_value = lkv )
107+
84108 # Code in checker.py should merge any extra_items where possible, so we
85109 # should have only compatible extra_items here. We check this before
86110 # the below subtype check, so that extra_attrs will not get erased.
@@ -94,36 +118,6 @@ def meet_types(s: Type, t: Type) -> ProperType:
94118 return s
95119 return t
96120
97- # special casing for dealing with last known values
98- if is_proper_subtype (s , t , ignore_promotions = True ) and is_proper_subtype (
99- t , s , ignore_promotions = True
100- ):
101- lkv : LiteralType | None
102- if s .last_known_value is None and t .last_known_value is None :
103- # Both types have no last known value, so we return the original type.
104- lkv = None
105- elif s .last_known_value is None and t .last_known_value is not None :
106- lkv = t .last_known_value
107- elif s .last_known_value is not None and t .last_known_value is None :
108- lkv = s .last_known_value
109- elif s .last_known_value is not None and t .last_known_value is not None :
110- lkv_meet = meet_types (s .last_known_value , t .last_known_value )
111- if isinstance (lkv_meet , UninhabitedType ):
112- lkv = None
113- elif isinstance (lkv_meet , LiteralType ):
114- lkv = lkv_meet
115- else :
116- msg = (
117- f"Unexpected meet result for last known values: "
118- f"{ s .last_known_value = } and { t .last_known_value = } "
119- f"resulted in { lkv_meet = } "
120- )
121- raise ValueError (msg )
122- else :
123- assert False
124- assert lkv is None or isinstance (lkv , LiteralType )
125- return t .copy_modified (last_known_value = lkv )
126-
127121 if not isinstance (s , UnboundType ) and not isinstance (t , UnboundType ):
128122 if is_proper_subtype (s , t , ignore_promotions = True ):
129123 return s
0 commit comments