# Buggy code
def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
    # OverloadedFuncDef refers to any legitimate situation where you have
    # more than one declaration for the same function in a row.  This occurs
    # with a @property with a setter or a deleter, and for a classic
    # @overload.

    # Decide whether to analyze this as a property or an overload.  If an
    # overload, and we're outside a stub, find the impl and set it.  Remove
    # the impl from the item list, it's special.
    types = []  # type: List[CallableType]
    non_overload_indexes = []

    # See if the first item is a property (and not an overload)
    first_item = defn.items[0]
    first_item.is_overload = True
    first_item.accept(self)

    defn._fullname = self.qualified_name(defn.name())

    if isinstance(first_item, Decorator) and first_item.func.is_property:
        first_item.func.is_overload = True
        self.analyze_property_with_multi_part_definition(defn)
        typ = function_type(first_item.func, self.builtin_type("builtins.function"))
        assert isinstance(typ, CallableType)
        types = [typ]
    else:
        for i, item in enumerate(defn.items):
            if i != 0:
                # The first item was already visited
                item.is_overload = True
                item.accept(self)
            # TODO support decorated overloaded functions properly
            if isinstance(item, Decorator):
                callable = function_type(
                    item.func, self.builtin_type("builtins.function")
                )
                assert isinstance(callable, CallableType)
                if not any(
                    refers_to_fullname(dec, "typing.overload")
                    for dec in item.decorators
                ):
                    if i == len(defn.items) - 1 and not self.is_stub_file:
                        # Last item outside a stub is impl
                        defn.impl = item
                    else:
                        # Oops it wasn't an overload after all. A clear error
                        # will vary based on where in the list it is, record
                        # that.
                        non_overload_indexes.append(i)
                else:
                    item.func.is_overload = True
                    types.append(callable)
            elif isinstance(item, FuncDef):
                if i == len(defn.items) - 1 and not self.is_stub_file:
                    defn.impl = item
                else:
                    non_overload_indexes.append(i)
        if non_overload_indexes:
            if types:
                # Some of them were overloads, but not all.
                for idx in non_overload_indexes:
                    if self.is_stub_file:
                        self.fail(
                            "An implementation for an overloaded function "
                            "is not allowed in a stub file",
                            defn.items[idx],
                        )
                    else:
                        self.fail(
                            "The implementation for an overloaded function "
                            "must come last",
                            defn.items[idx],
                        )
            else:
                for idx in non_overload_indexes[1:]:
                    self.name_already_defined(defn.name(), defn.items[idx], first_item)
                if defn.impl:
                    self.name_already_defined(defn.name(), defn.impl, first_item)
            # Remove the non-overloads
            for idx in reversed(non_overload_indexes):
                del defn.items[idx]
        # If we found an implementation, remove it from the overloads to
        # consider.
        if defn.impl is not None:
            assert defn.impl is defn.items[-1]
            defn.items = defn.items[:-1]
        elif not self.is_stub_file and not non_overload_indexes:
            if not (self.type and not self.is_func_scope() and self.type.is_protocol):
                self.fail(
                    "An overloaded function outside a stub file must have an implementation",
                    defn,
                )
            else:
                for item in defn.items:
                    if isinstance(item, Decorator):
                        item.func.is_abstract = True
                    else:
                        item.is_abstract = True

    if types:
        defn.type = Overloaded(types)
        defn.type.line = defn.line

    if not defn.items:
        # It was not any kind of overload def after all. We've visited the
        # redefinitions already.
        return

    # We know this is an overload def -- let's handle classmethod and staticmethod
    class_status = []
    static_status = []
    for item in defn.items:
        if isinstance(item, Decorator):
            inner = item.func
        elif isinstance(item, FuncDef):
            inner = item
        else:
            assert False, "The 'item' variable is an unexpected type: {}".format(
                type(item)
            )
        class_status.append(inner.is_class)
        static_status.append(inner.is_static)

    if defn.impl is not None:
        if isinstance(defn.impl, Decorator):
            inner = defn.impl.func
        elif isinstance(defn.impl, FuncDef):
            inner = defn.impl
        else:
            assert False, "Unexpected impl type: {}".format(type(defn.impl))
        class_status.append(inner.is_class)
        static_status.append(inner.is_static)

    if len(set(class_status)) != 1:
        self.msg.overload_inconsistently_applies_decorator("classmethod", defn)
    elif len(set(static_status)) != 1:
        self.msg.overload_inconsistently_applies_decorator("staticmethod", defn)
    else:
        defn.is_class = class_status[0]
        defn.is_static = static_status[0]

    if self.type and not self.is_func_scope():
        self.type.names[defn.name()] = SymbolTableNode(MDEF, defn)
        defn.info = self.type
    elif self.is_func_scope():
        self.add_local(defn, defn)


# Traceback (IndexError)
..\probes\test.py:3: error: Name 'TypeVar' is not defined
..\probes\test.py:12: error: Name 'bar' already defined on line 8
..\probes\test.py:1: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.610+dev-89c73ed2462e18d217bbd73be09d5085ff7f2632
Traceback (most recent call last):
File "C:\Python3.6\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Python3.6\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\Michael\mypy\__main__.py", line 11, in <module>
main(None)
File "C:\Users\Michael\mypy\main.py", line 91, in main
res = type_check_only(sources, bin_dir, options, flush_errors, fscache)  # noqa
File "C:\Users\Michael\mypy\main.py", line 148, in type_check_only
fscache=fscache)
File "C:\Users\Michael\mypy\build.py", line 181, in build
flush_errors, fscache)
File "C:\Users\Michael\mypy\build.py", line 286, in _build
graph = dispatch(sources, manager)
File "C:\Users\Michael\mypy\build.py", line 2440, in dispatch
process_graph(graph, manager)
File "C:\Users\Michael\mypy\build.py", line 2733, in process_graph
process_stale_scc(graph, scc, manager)
File "C:\Users\Michael\mypy\build.py", line 2845, in process_stale_scc
graph[id].semantic_analysis_pass_three()
File "C:\Users\Michael\mypy\build.py", line 2059, in semantic_analysis_pass_three
self.options, patches)
File "C:\Users\Michael\mypy\semanal_pass3.py", line 71, in visit_file
self.accept(file_node)
File "C:\Users\Michael\mypy\semanal_pass3.py", line 96, in accept
node.accept(self)
File "C:\Users\Michael\mypy\nodes.py", line 246, in accept
return visitor.visit_mypy_file(self)
File "C:\Users\Michael\mypy\traverser.py", line 30, in visit_mypy_file
d.accept(self)
File "C:\Users\Michael\mypy\nodes.py", line 432, in accept
return visitor.visit_overloaded_func_def(self)
File "C:\Users\Michael\mypy\semanal_pass3.py", line 117, in visit_overloaded_func_def
super().visit_overloaded_func_def(fdef)
File "C:\Users\Michael\mypy\traverser.py", line 55, in visit_overloaded_func_def
o.impl.accept(self)
File "C:\Users\Michael\mypy\nodes.py", line 663, in accept
return visitor.visit_decorator(self)
File "C:\Users\Michael\mypy\semanal_pass3.py", line 170, in visit_decorator
dec.func.accept(self)
File "C:\Users\Michael\mypy\nodes.py", line 586, in accept
return visitor.visit_func_def(self)
File "C:\Users\Michael\mypy\semanal_pass3.py", line 109, in visit_func_def
self.analyze(fdef.type, fdef)
File "C:\Users\Michael\mypy\semanal_pass3.py", line 380, in analyze
type.accept(analyzer)
File "C:\Users\Michael\mypy\types.py", line 797, in accept
return visitor.visit_callable_type(self)
File "C:\Users\Michael\mypy\typeanal.py", line 760, in visit_callable_type
t.ret_type.accept(self)
File "C:\Users\Michael\mypy\types.py", line 1486, in accept

return visitor.visit_forwardref_type(self)
File "C:\Users\Michael\mypy\typeanal.py", line 819, in visit_forwardref_type
resolved = self.anal_type(t.unbound)
File "C:\Users\Michael\mypy\typeanal.py", line 829, in anal_type
res = tp.accept(tpan)
File "C:\Users\Michael\mypy\types.py", line 204, in accept
return visitor.visit_unbound_type(self)
File "C:\Users\Michael\mypy\typeanal.py", line 178, in visit_unbound_type
typ = self.visit_unbound_type_nonoptional(t)
File "C:\Users\Michael\mypy\typeanal.py", line 334, in visit_unbound_type_nonoptional
self.fail('Invalid type "{}"'.format(name), t)
File "C:\Users\Michael\mypy\typeanal.py", line 551, in fail

self.fail_func(msg, ctx)
File "C:\Users\Michael\mypy\semanal_pass3.py", line 468, in fail
self.sem.fail(msg, ctx, serious, blocker=blocker)
File "C:\Users\Michael\mypy\semanal.py", line 3281, in fail

self.errors.report(ctx.get_line(), ctx.get_column(), msg, blocker=blocker)
File "C:\Users\Michael\mypy\errors.py", line 247, in report

function = self.scope.current_function_name()
File "C:\Users\Michael\mypy\scope.py", line 50, in current_function_name
return self.function.name() if self.function else None
File "C:\Users\Michael\mypy\nodes.py", line 429, in name
return self.items[0].name()
IndexError: list index out of range
..\probes\test.py:1: : note: use --pdb to drop into pdb

# Fixed code
def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
    # OverloadedFuncDef refers to any legitimate situation where you have
    # more than one declaration for the same function in a row.  This occurs
    # with a @property with a setter or a deleter, and for a classic
    # @overload.

    # Decide whether to analyze this as a property or an overload.  If an
    # overload, and we're outside a stub, find the impl and set it.  Remove
    # the impl from the item list, it's special.
    types = []  # type: List[CallableType]
    non_overload_indexes = []

    # See if the first item is a property (and not an overload)
    first_item = defn.items[0]
    first_item.is_overload = True
    first_item.accept(self)

    defn._fullname = self.qualified_name(defn.name())

    if isinstance(first_item, Decorator) and first_item.func.is_property:
        first_item.func.is_overload = True
        self.analyze_property_with_multi_part_definition(defn)
        typ = function_type(first_item.func, self.builtin_type("builtins.function"))
        assert isinstance(typ, CallableType)
        types = [typ]
    else:
        for i, item in enumerate(defn.items):
            if i != 0:
                # The first item was already visited
                item.is_overload = True
                item.accept(self)
            # TODO: support decorated overloaded functions properly
            if isinstance(item, Decorator):
                callable = function_type(
                    item.func, self.builtin_type("builtins.function")
                )
                assert isinstance(callable, CallableType)
                if not any(
                    refers_to_fullname(dec, "typing.overload")
                    for dec in item.decorators
                ):
                    if i == len(defn.items) - 1 and not self.is_stub_file:
                        # Last item outside a stub is impl
                        defn.impl = item
                    else:
                        # Oops it wasn't an overload after all. A clear error
                        # will vary based on where in the list it is, record
                        # that.
                        non_overload_indexes.append(i)
                else:
                    item.func.is_overload = True
                    types.append(callable)
            elif isinstance(item, FuncDef):
                if i == len(defn.items) - 1 and not self.is_stub_file:
                    defn.impl = item
                else:
                    non_overload_indexes.append(i)
        if non_overload_indexes:
            if types:
                # Some of them were overloads, but not all.
                for idx in non_overload_indexes:
                    if self.is_stub_file:
                        self.fail(
                            "An implementation for an overloaded function "
                            "is not allowed in a stub file",
                            defn.items[idx],
                        )
                    else:
                        self.fail(
                            "The implementation for an overloaded function "
                            "must come last",
                            defn.items[idx],
                        )
            else:
                for idx in non_overload_indexes[1:]:
                    self.name_already_defined(defn.name(), defn.items[idx], first_item)
                if defn.impl:
                    self.name_already_defined(defn.name(), defn.impl, first_item)
            # Remove the non-overloads
            for idx in reversed(non_overload_indexes):
                del defn.items[idx]
        # If we found an implementation, remove it from the overloads to
        # consider.
        if defn.impl is not None:
            assert defn.impl is defn.items[-1]
            defn.items = defn.items[:-1]
        elif not self.is_stub_file and not non_overload_indexes:
            if not (self.type and not self.is_func_scope() and self.type.is_protocol):
                self.fail(
                    "An overloaded function outside a stub file must have an implementation",
                    defn,
                )
            else:
                for item in defn.items:
                    if isinstance(item, Decorator):
                        item.func.is_abstract = True
                    else:
                        item.is_abstract = True

    if types:
        defn.type = Overloaded(types)
        defn.type.line = defn.line

    if not defn.items:
        # It was not any kind of overload def after all. We've visited the
        # redefinitions already.
        return

    # We know this is an overload def -- let's handle classmethod and staticmethod
    class_status = []
    static_status = []
    for item in defn.items:
        if isinstance(item, Decorator):
            inner = item.func
        elif isinstance(item, FuncDef):
            inner = item
        else:
            assert False, "The 'item' variable is an unexpected type: {}".format(
                type(item)
            )
        class_status.append(inner.is_class)
        static_status.append(inner.is_static)

    if defn.impl is not None:
        if isinstance(defn.impl, Decorator):
            inner = defn.impl.func
        elif isinstance(defn.impl, FuncDef):
            inner = defn.impl
        else:
            assert False, "Unexpected impl type: {}".format(type(defn.impl))
        class_status.append(inner.is_class)
        static_status.append(inner.is_static)

    if len(set(class_status)) != 1:
        self.msg.overload_inconsistently_applies_decorator("classmethod", defn)
    elif len(set(static_status)) != 1:
        self.msg.overload_inconsistently_applies_decorator("staticmethod", defn)
    else:
        defn.is_class = class_status[0]
        defn.is_static = static_status[0]

    if self.type and not self.is_func_scope():
        self.type.names[defn.name()] = SymbolTableNode(MDEF, defn)
        defn.info = self.type
    elif self.is_func_scope():
        self.add_local(defn, defn)