@@ -631,7 +631,7 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
631
631
ret : list [Statement ] = []
632
632
current_overload : list [OverloadPart ] = []
633
633
current_overload_name : str | None = None
634
- seen_unconditional_func_def = False
634
+ last_unconditional_func_def : str | None = None
635
635
last_if_stmt : IfStmt | None = None
636
636
last_if_overload : Decorator | FuncDef | OverloadedFuncDef | None = None
637
637
last_if_stmt_overload_name : str | None = None
@@ -641,7 +641,7 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
641
641
if_overload_name : str | None = None
642
642
if_block_with_overload : Block | None = None
643
643
if_unknown_truth_value : IfStmt | None = None
644
- if isinstance (stmt , IfStmt ) and seen_unconditional_func_def is False :
644
+ if isinstance (stmt , IfStmt ):
645
645
# Check IfStmt block to determine if function overloads can be merged
646
646
if_overload_name = self ._check_ifstmt_for_overloads (stmt , current_overload_name )
647
647
if if_overload_name is not None :
@@ -669,11 +669,18 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
669
669
last_if_unknown_truth_value = None
670
670
current_overload .append (stmt )
671
671
if isinstance (stmt , FuncDef ):
672
- seen_unconditional_func_def = True
672
+ # This is, strictly speaking, wrong: there might be a decorated
673
+ # implementation. However, it only affects the error message we show:
674
+ # ideally it's "already defined", but "implementation must come last"
675
+ # is also reasonable.
676
+ # TODO: can we get rid of this completely and just always emit
677
+ # "implementation must come last" instead?
678
+ last_unconditional_func_def = stmt .name
673
679
elif (
674
680
current_overload_name is not None
675
681
and isinstance (stmt , IfStmt )
676
682
and if_overload_name == current_overload_name
683
+ and last_unconditional_func_def != current_overload_name
677
684
):
678
685
# IfStmt only contains stmts relevant to current_overload.
679
686
# Check if stmts are reachable and add them to current_overload,
@@ -729,7 +736,7 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
729
736
# most of mypy/mypyc assumes that all the functions in an OverloadedFuncDef are
730
737
# related, but multiple underscore functions next to each other aren't necessarily
731
738
# related
732
- seen_unconditional_func_def = False
739
+ last_unconditional_func_def = None
733
740
if isinstance (stmt , Decorator ) and not unnamed_function (stmt .name ):
734
741
current_overload = [stmt ]
735
742
current_overload_name = stmt .name
0 commit comments