@@ -65,27 +65,86 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
65
65
|| class_metadata. is_some_and ( |idx| self . get_idx ( * idx) . is_protocol ( ) ) ;
66
66
let def = self . get_idx ( idx) ;
67
67
if def. metadata . flags . is_overload {
68
+ if !skip_implementation && def. stub_or_impl == FunctionStubOrImpl :: Impl {
69
+ self . error (
70
+ errors,
71
+ def. id_range ,
72
+ ErrorKind :: InvalidOverload ,
73
+ None ,
74
+ "@overload decorator should not be used on function implementations." . to_owned ( ) ,
75
+ ) ;
76
+ }
77
+
68
78
// This function is decorated with @overload. We should warn if this function is actually called anywhere.
69
79
let successor = self . bindings ( ) . get ( idx) . successor ;
70
80
let ty = def. ty . clone ( ) ;
71
81
if successor. is_none ( ) {
72
82
// This is the last definition in the chain. We should produce an overload type.
73
83
let mut acc = Vec1 :: new ( ( def. id_range , ty) ) ;
74
- let mut first = def;
75
- while let Some ( def) = self . step_overload_pred ( predecessor) {
76
- acc. push ( ( def. id_range , def. ty . clone ( ) ) ) ;
77
- first = def;
84
+ let mut has_overload_after = false ;
85
+ let mut has_implementation_before_overload = false ;
86
+ let mut has_any_implementation = false ;
87
+ let mut temp_pred = * predecessor;
88
+ while let Some ( current_pred_idx) = temp_pred {
89
+ let mut current_binding = self . bindings ( ) . get ( current_pred_idx) ;
90
+ while let Binding :: Forward ( forward_key) = current_binding {
91
+ current_binding = self . bindings ( ) . get ( * forward_key) ;
92
+ }
93
+ if let Binding :: Function ( func_idx, next_predecessor, _) = current_binding {
94
+ let func_def = self . get_idx ( * func_idx) ;
95
+
96
+ if func_def. metadata . flags . is_overload {
97
+ has_overload_after = true ;
98
+ }
99
+ if func_def. stub_or_impl == FunctionStubOrImpl :: Impl {
100
+ has_any_implementation = true ;
101
+ if !func_def. metadata . flags . is_overload {
102
+ has_implementation_before_overload = true ;
103
+ }
104
+ }
105
+ if has_overload_after && has_any_implementation && has_implementation_before_overload {
106
+ break ;
107
+ }
108
+ temp_pred = * next_predecessor;
109
+ } else {
110
+ break ;
111
+ }
112
+ }
113
+
114
+ let mut first = def. clone ( ) ;
115
+ while let Some ( predecessor_def) = self . step_overload_pred ( predecessor) {
116
+ acc. push ( ( predecessor_def. id_range , predecessor_def. ty . clone ( ) ) ) ;
117
+ first = predecessor_def;
78
118
}
79
119
if !skip_implementation {
80
- self . error (
81
- errors,
82
- first. id_range ,
83
- ErrorKind :: InvalidOverload ,
84
- None ,
85
- "Overloaded function must have an implementation" . to_owned ( ) ,
86
- ) ;
120
+ if !has_implementation_before_overload && def. stub_or_impl == FunctionStubOrImpl :: Impl {
121
+ self . error (
122
+ errors,
123
+ def. id_range ,
124
+ ErrorKind :: InvalidOverload ,
125
+ None ,
126
+ "@overload decorator should not be used on function implementations." . to_owned ( ) ,
127
+ ) ;
128
+ } else if has_any_implementation {
129
+ self . error (
130
+ errors,
131
+ def. id_range ,
132
+ ErrorKind :: InvalidOverload ,
133
+ None ,
134
+ "@overload declarations must come before function implementation. " . to_owned ( ) ,
135
+ ) ;
136
+ }
137
+ else {
138
+ self . error (
139
+ errors,
140
+ first. id_range ,
141
+ ErrorKind :: InvalidOverload ,
142
+ None ,
143
+ "Overloaded function must have an implementation" . to_owned ( ) ,
144
+ ) ;
145
+ }
87
146
}
88
- if acc. len ( ) == 1 {
147
+ if acc. len ( ) == 1 && !has_overload_after && !has_any_implementation {
89
148
self . error (
90
149
errors,
91
150
first. id_range ,
@@ -110,29 +169,7 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
110
169
}
111
170
} else {
112
171
let mut acc = Vec :: new ( ) ;
113
- let implementation_range = def. id_range ;
114
172
let mut first = def;
115
- let mut has_overload_successor = false ;
116
-
117
- let binding = self . bindings ( ) . get ( idx) ;
118
- let mut current_successor = binding. successor ;
119
- while let Some ( succ_key_idx) = current_successor {
120
- let succ_def = self . get_idx ( succ_key_idx) ;
121
- if succ_def. metadata . flags . is_overload {
122
- has_overload_successor = true ;
123
- break ;
124
- }
125
- current_successor = self . bindings ( ) . get ( succ_key_idx) . successor ;
126
- }
127
- if has_overload_successor && !skip_implementation {
128
- self . error (
129
- errors,
130
- implementation_range,
131
- ErrorKind :: InvalidOverload ,
132
- None ,
133
- "Function implementation must come after all @overload declarations. " . to_owned ( ) ,
134
- ) ;
135
- }
136
173
while let Some ( def) = self . step_overload_pred ( predecessor) {
137
174
acc. push ( ( def. id_range , def. ty . clone ( ) ) ) ;
138
175
first = def;
@@ -247,16 +284,6 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
247
284
self_type = self_type. map ( Type :: type_form) ;
248
285
}
249
286
250
- if is_overload && stub_or_impl == FunctionStubOrImpl :: Impl {
251
- self . error (
252
- errors,
253
- def. name . range ,
254
- ErrorKind :: InvalidOverload ,
255
- None ,
256
- "@overload decorator should not be used on function implementations." . to_owned ( ) ,
257
- ) ;
258
- }
259
-
260
287
// Determine the type of the parameter based on its binding. Left is annotated parameter, right is unannotated
261
288
let mut get_param_ty = |name : & Identifier , default : Option < & Expr > | {
262
289
let ty = match self . bindings ( ) . get_function_param ( name) {
@@ -495,6 +522,7 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
495
522
id_range : def. name . range ,
496
523
ty,
497
524
metadata,
525
+ stub_or_impl,
498
526
} )
499
527
}
500
528
0 commit comments