@@ -312,6 +312,8 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
312
312
actual = actual .as_anonymous ().fallback
313
313
if isinstance (actual , Instance ):
314
314
instance = actual
315
+ erased = erase_typevars (template )
316
+ assert isinstance (erased , Instance )
315
317
# We always try nominal inference if possible,
316
318
# it is much faster than the structural one.
317
319
if (self .direction == SUBTYPE_OF and
@@ -343,8 +345,11 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
343
345
# This is a conservative way break the inference cycles.
344
346
# It never produces any "false" constraints but gives up soon
345
347
# on purely structural inference cycles, see #3829.
348
+ # Note that we use is_protocol_implementation instead of is_subtype
349
+ # because some type may be considered a subtype of a protocol
350
+ # due to _promote, but still not implement the protocol.
346
351
not any (is_same_type (template , t ) for t in template .type .inferring ) and
347
- mypy .subtypes .is_subtype (instance , erase_typevars ( template ) )):
352
+ mypy .subtypes .is_protocol_implementation (instance , erased )):
348
353
template .type .inferring .append (template )
349
354
self .infer_constraints_from_protocol_members (res , instance , template ,
350
355
original_actual , template )
@@ -353,7 +358,7 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
353
358
elif (instance .type .is_protocol and self .direction == SUBTYPE_OF and
354
359
# We avoid infinite recursion for structural subtypes also here.
355
360
not any (is_same_type (instance , i ) for i in instance .type .inferring ) and
356
- mypy .subtypes .is_subtype ( erase_typevars ( template ) , instance )):
361
+ mypy .subtypes .is_protocol_implementation ( erased , instance )):
357
362
instance .type .inferring .append (instance )
358
363
self .infer_constraints_from_protocol_members (res , instance , template ,
359
364
template , instance )
0 commit comments