@@ -629,7 +629,7 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
629629 ret : list [Statement ] = []
630630 current_overload : list [OverloadPart ] = []
631631 current_overload_name : str | None = None
632- seen_unconditional_func_def = False
632+ last_unconditional_func_def : str | None = None
633633 last_if_stmt : IfStmt | None = None
634634 last_if_overload : Decorator | FuncDef | OverloadedFuncDef | None = None
635635 last_if_stmt_overload_name : str | None = None
@@ -639,7 +639,7 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
639639 if_overload_name : str | None = None
640640 if_block_with_overload : Block | None = None
641641 if_unknown_truth_value : IfStmt | None = None
642- if isinstance (stmt , IfStmt ) and seen_unconditional_func_def is False :
642+ if isinstance (stmt , IfStmt ):
643643 # Check IfStmt block to determine if function overloads can be merged
644644 if_overload_name = self ._check_ifstmt_for_overloads (stmt , current_overload_name )
645645 if if_overload_name is not None :
@@ -667,11 +667,18 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
667667 last_if_unknown_truth_value = None
668668 current_overload .append (stmt )
669669 if isinstance (stmt , FuncDef ):
670- seen_unconditional_func_def = True
670+ # This is, strictly speaking, wrong: there might be a decorated
671+ # implementation. However, it only affects the error message we show:
672+ # ideally it's "already defined", but "implementation must come last"
673+ # is also reasonable.
674+ # TODO: can we get rid of this completely and just always emit
675+ # "implementation must come last" instead?
676+ last_unconditional_func_def = stmt .name
671677 elif (
672678 current_overload_name is not None
673679 and isinstance (stmt , IfStmt )
674680 and if_overload_name == current_overload_name
681+ and last_unconditional_func_def != current_overload_name
675682 ):
676683 # IfStmt only contains stmts relevant to current_overload.
677684 # Check if stmts are reachable and add them to current_overload,
@@ -727,7 +734,7 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
727734 # most of mypy/mypyc assumes that all the functions in an OverloadedFuncDef are
728735 # related, but multiple underscore functions next to each other aren't necessarily
729736 # related
730- seen_unconditional_func_def = False
737+ last_unconditional_func_def = None
731738 if isinstance (stmt , Decorator ) and not unnamed_function (stmt .name ):
732739 current_overload = [stmt ]
733740 current_overload_name = stmt .name
0 commit comments