# Buggy code
def visit_instance(self, template: Instance) -> List[Constraint]:
    original_actual = actual = self.actual
    res = []  # type: List[Constraint]
    if isinstance(actual, (CallableType, Overloaded)) and template.type.is_protocol:
        if template.type.protocol_members == ["__call__"]:
            # Special case: a generic callback protocol
            if not any(
                mypy.sametypes.is_same_type(template, t)
                for t in template.type.inferring
            ):
                template.type.inferring.append(template)
                call = mypy.subtypes.find_member(
                    "__call__", template, actual, is_operator=True
                )
                assert call is not None
                if mypy.subtypes.is_subtype(actual, erase_typevars(call)):
                    subres = infer_constraints(call, actual, self.direction)
                    res.extend(subres)
                template.type.inferring.pop()
                return res
    if isinstance(actual, CallableType) and actual.fallback is not None:
        actual = actual.fallback
    if isinstance(actual, Overloaded) and actual.fallback is not None:
        actual = actual.fallback
    if isinstance(actual, TypedDictType):
        actual = actual.as_anonymous().fallback
    if isinstance(actual, LiteralType):
        actual = actual.fallback
    if isinstance(actual, Instance):
        instance = actual
        erased = erase_typevars(template)
        assert isinstance(erased, Instance)  # type: ignore
        # We always try nominal inference if possible,
        # it is much faster than the structural one.
        if self.direction == SUBTYPE_OF and template.type.has_base(
            instance.type.fullname
        ):
            mapped = map_instance_to_supertype(template, instance.type)
            tvars = mapped.type.defn.type_vars
            for i in range(len(instance.args)):
                # The constraints for generic type parameters depend on variance.
                # Include constraints from both directions if invariant.
                if tvars[i].variance != CONTRAVARIANT:
                    res.extend(
                        infer_constraints(
                            mapped.args[i], instance.args[i], self.direction
                        )
                    )
                if tvars[i].variance != COVARIANT:
                    res.extend(
                        infer_constraints(
                            mapped.args[i], instance.args[i], neg_op(self.direction)
                        )
                    )
            return res
        elif self.direction == SUPERTYPE_OF and instance.type.has_base(
            template.type.fullname
        ):
            mapped = map_instance_to_supertype(instance, template.type)
            tvars = template.type.defn.type_vars
            for j in range(len(template.args)):
                # The constraints for generic type parameters depend on variance.
                # Include constraints from both directions if invariant.
                if tvars[j].variance != CONTRAVARIANT:
                    res.extend(
                        infer_constraints(
                            template.args[j], mapped.args[j], self.direction
                        )
                    )
                if tvars[j].variance != COVARIANT:
                    res.extend(
                        infer_constraints(
                            template.args[j], mapped.args[j], neg_op(self.direction)
                        )
                    )
            return res
        if (
            template.type.is_protocol
            and self.direction == SUPERTYPE_OF
            and
            # We avoid infinite recursion for structural subtypes by checking
            # whether this type already appeared in the inference chain.
            # This is a conservative way break the inference cycles.
            # It never produces any "false" constraints but gives up soon
            # on purely structural inference cycles, see #3829.
            # Note that we use is_protocol_implementation instead of is_subtype
            # because some type may be considered a subtype of a protocol
            # due to _promote, but still not implement the protocol.
            not any(
                mypy.sametypes.is_same_type(template, t)
                for t in template.type.inferring
            )
            and mypy.subtypes.is_protocol_implementation(instance, erased)
        ):
            template.type.inferring.append(template)
            self.infer_constraints_from_protocol_members(
                res, instance, template, original_actual, template
            )
            template.type.inferring.pop()
            return res
        elif (
            instance.type.is_protocol
            and self.direction == SUBTYPE_OF
            and
            # We avoid infinite recursion for structural subtypes also here.
            not any(
                mypy.sametypes.is_same_type(instance, i)
                for i in instance.type.inferring
            )
            and mypy.subtypes.is_protocol_implementation(erased, instance)
        ):
            instance.type.inferring.append(instance)
            self.infer_constraints_from_protocol_members(
                res, instance, template, template, instance
            )
            instance.type.inferring.pop()
            return res
    if isinstance(actual, AnyType):
        # IDEA: Include both ways, i.e. add negation as well?
        return self.infer_against_any(template.args, actual)
    if (
        isinstance(actual, TupleType)
        and (
            is_named_instance(template, "typing.Iterable")
            or is_named_instance(template, "typing.Container")
            or is_named_instance(template, "typing.Sequence")
            or is_named_instance(template, "typing.Reversible")
        )
        and self.direction == SUPERTYPE_OF
    ):
        for item in actual.items:
            cb = infer_constraints(template.args[0], item, SUPERTYPE_OF)
            res.extend(cb)
        return res
    elif isinstance(actual, TupleType) and self.direction == SUPERTYPE_OF:
        return infer_constraints(
            template, mypy.typeops.tuple_fallback(actual), self.direction
        )
    else:
        return []


# Traceback (IndexError)
$ mypy --quick --show-traceback a.py
b.py:7: error: Revealed type is 'def () -> b.C'
/Users/jukka/src/mypy/b.py:11: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.510-dev-c856a53fe06c0ad9193d86ab35fb86693940f273-dirty
Traceback (most recent call last):
File "/Users/jukka/src/mypy/scripts/mypy", line 6, in <module>
main(__file__)
File "/Users/jukka/src/mypy/mypy/main.py", line 46, in main
res = type_check_only(sources, bin_dir, options)
File "/Users/jukka/src/mypy/mypy/main.py", line 93, in type_check_only
options=options)
File "/Users/jukka/src/mypy/mypy/build.py", line 188, in build
graph = dispatch(sources, manager)
File "/Users/jukka/src/mypy/mypy/build.py", line 1570, in dispatch
process_graph(graph, manager)
File "/Users/jukka/src/mypy/mypy/build.py", line 1813, in process_graph
process_stale_scc(graph, scc, manager)
File "/Users/jukka/src/mypy/mypy/build.py", line 1912, in process_stale_scc
graph[id].type_check_first_pass()
File "/Users/jukka/src/mypy/mypy/build.py", line 1485, in type_check_first_pass
self.type_checker.check_first_pass()
File "/Users/jukka/src/mypy/mypy/checker.py", line 177, in check_first_pass
self.accept(d)
File "/Users/jukka/src/mypy/mypy/checker.py", line 262, in accept
stmt.accept(self)
File "/Users/jukka/src/mypy/mypy/nodes.py", line 853, in accept
return visitor.visit_assignment_stmt(self)
File "/Users/jukka/src/mypy/mypy/checker.py", line 1177, in visit_assignment_stmt
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
File "/Users/jukka/src/mypy/mypy/checker.py", line 1239, in check_assignment
rvalue_type = self.check_simple_assignment(lvalue_type, rvalue, lvalue)
File "/Users/jukka/src/mypy/mypy/checker.py", line 1698, in check_simple_assignment
rvalue_type = self.expr_checker.accept(rvalue, lvalue_type)
File "/Users/jukka/src/mypy/mypy/checkexpr.py", line 2056, in accept
typ = node.accept(self)
File "/Users/jukka/src/mypy/mypy/nodes.py", line 1213, in accept
return visitor.visit_name_expr(self)
File "/Users/jukka/src/mypy/mypy/checkexpr.py", line 123, in visit_name_expr
return self.narrow_type_from_binder(e, result)
File "/Users/jukka/src/mypy/mypy/checkexpr.py", line 2271, in narrow_type_from_binder
ans = narrow_declared_type(known_type, restriction)
File "/Users/jukka/src/mypy/mypy/meet.py", line 46, in narrow_declared_type
return meet_types(declared, narrowed)
File "/Users/jukka/src/mypy/mypy/meet.py", line 25, in meet_types
return t.accept(TypeMeetVisitor(s))
File "/Users/jukka/src/mypy/mypy/types.py", line 381, in accept
return visitor.visit_instance(self)
File "/Users/jukka/src/mypy/mypy/meet.py", line 198, in visit_instance
args.append(self.meet(t.args[i], si.args[i]))
IndexError: list index out of range
/Users/jukka/src/mypy/b.py:11: note: use --pdb to drop into pdb

# Fixed code
def visit_instance(self, template: Instance) -> List[Constraint]:
    original_actual = actual = self.actual
    res = []  # type: List[Constraint]
    if isinstance(actual, (CallableType, Overloaded)) and template.type.is_protocol:
        if template.type.protocol_members == ["__call__"]:
            # Special case: a generic callback protocol
            if not any(
                mypy.sametypes.is_same_type(template, t)
                for t in template.type.inferring
            ):
                template.type.inferring.append(template)
                call = mypy.subtypes.find_member(
                    "__call__", template, actual, is_operator=True
                )
                assert call is not None
                if mypy.subtypes.is_subtype(actual, erase_typevars(call)):
                    subres = infer_constraints(call, actual, self.direction)
                    res.extend(subres)
                template.type.inferring.pop()
                return res
    if isinstance(actual, CallableType) and actual.fallback is not None:
        actual = actual.fallback
    if isinstance(actual, Overloaded) and actual.fallback is not None:
        actual = actual.fallback
    if isinstance(actual, TypedDictType):
        actual = actual.as_anonymous().fallback
    if isinstance(actual, LiteralType):
        actual = actual.fallback
    if isinstance(actual, Instance):
        instance = actual
        erased = erase_typevars(template)
        assert isinstance(erased, Instance)  # type: ignore
        # We always try nominal inference if possible,
        # it is much faster than the structural one.
        if self.direction == SUBTYPE_OF and template.type.has_base(
            instance.type.fullname
        ):
            mapped = map_instance_to_supertype(template, instance.type)
            tvars = mapped.type.defn.type_vars
            # N.B: We use zip instead of indexing because the lengths might have
            # mismatches during daemon reprocessing.
            for tvar, mapped_arg, instance_arg in zip(
                tvars, mapped.args, instance.args
            ):
                # The constraints for generic type parameters depend on variance.
                # Include constraints from both directions if invariant.
                if tvar.variance != CONTRAVARIANT:
                    res.extend(
                        infer_constraints(mapped_arg, instance_arg, self.direction)
                    )
                if tvar.variance != COVARIANT:
                    res.extend(
                        infer_constraints(
                            mapped_arg, instance_arg, neg_op(self.direction)
                        )
                    )
            return res
        elif self.direction == SUPERTYPE_OF and instance.type.has_base(
            template.type.fullname
        ):
            mapped = map_instance_to_supertype(instance, template.type)
            tvars = template.type.defn.type_vars
            # N.B: We use zip instead of indexing because the lengths might have
            # mismatches during daemon reprocessing.
            for tvar, mapped_arg, template_arg in zip(
                tvars, mapped.args, template.args
            ):
                # The constraints for generic type parameters depend on variance.
                # Include constraints from both directions if invariant.
                if tvar.variance != CONTRAVARIANT:
                    res.extend(
                        infer_constraints(template_arg, mapped_arg, self.direction)
                    )
                if tvar.variance != COVARIANT:
                    res.extend(
                        infer_constraints(
                            template_arg, mapped_arg, neg_op(self.direction)
                        )
                    )
            return res
        if (
            template.type.is_protocol
            and self.direction == SUPERTYPE_OF
            and
            # We avoid infinite recursion for structural subtypes by checking
            # whether this type already appeared in the inference chain.
            # This is a conservative way break the inference cycles.
            # It never produces any "false" constraints but gives up soon
            # on purely structural inference cycles, see #3829.
            # Note that we use is_protocol_implementation instead of is_subtype
            # because some type may be considered a subtype of a protocol
            # due to _promote, but still not implement the protocol.
            not any(
                mypy.sametypes.is_same_type(template, t)
                for t in template.type.inferring
            )
            and mypy.subtypes.is_protocol_implementation(instance, erased)
        ):
            template.type.inferring.append(template)
            self.infer_constraints_from_protocol_members(
                res, instance, template, original_actual, template
            )
            template.type.inferring.pop()
            return res
        elif (
            instance.type.is_protocol
            and self.direction == SUBTYPE_OF
            and
            # We avoid infinite recursion for structural subtypes also here.
            not any(
                mypy.sametypes.is_same_type(instance, i)
                for i in instance.type.inferring
            )
            and mypy.subtypes.is_protocol_implementation(erased, instance)
        ):
            instance.type.inferring.append(instance)
            self.infer_constraints_from_protocol_members(
                res, instance, template, template, instance
            )
            instance.type.inferring.pop()
            return res
    if isinstance(actual, AnyType):
        # IDEA: Include both ways, i.e. add negation as well?
        return self.infer_against_any(template.args, actual)
    if (
        isinstance(actual, TupleType)
        and (
            is_named_instance(template, "typing.Iterable")
            or is_named_instance(template, "typing.Container")
            or is_named_instance(template, "typing.Sequence")
            or is_named_instance(template, "typing.Reversible")
        )
        and self.direction == SUPERTYPE_OF
    ):
        for item in actual.items:
            cb = infer_constraints(template.args[0], item, SUPERTYPE_OF)
            res.extend(cb)
        return res
    elif isinstance(actual, TupleType) and self.direction == SUPERTYPE_OF:
        return infer_constraints(
            template, mypy.typeops.tuple_fallback(actual), self.direction
        )
    else:
        return []