Skip to content

Commit 253f8b1

Browse files
committed
Fix overload bug
Fix #770
1 parent 0a3ac89 commit 253f8b1

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

crates/emmylua_code_analysis/src/compilation/test/overload_test.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,18 @@ mod test {
5353
let expected = ws.ty("MyClass");
5454
assert_eq!(ws.humanize_type(ty), ws.humanize_type(expected));
5555
}
56+
57+
#[test]
58+
fn test_issue_770() {
59+
let mut ws = VirtualWorkspace::new_with_init_std_lib();
60+
assert!(ws.check_code_for(
61+
DiagnosticCode::RedundantParameter,
62+
r#"
63+
local table = {1,2}
64+
if next(table, 2) == '2' then
65+
print('ok')
66+
end
67+
"#
68+
));
69+
}
5670
}

crates/emmylua_code_analysis/src/semantic/overload_resolve/resolve_signature_by_args.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ pub fn resolve_signature_by_args(
101101
is_colon_call: bool,
102102
arg_count: Option<usize>,
103103
) -> InferCallFuncResult {
104-
let arg_count = arg_count.unwrap_or(0);
104+
let expr_len = expr_types.len();
105+
let arg_count = arg_count.unwrap_or(expr_len);
105106
let mut need_resolve_funcs = match overloads.len() {
106107
0 => return Err(InferFailReason::None),
107108
1 => return Ok(Arc::clone(&overloads[0])),
@@ -111,8 +112,7 @@ pub fn resolve_signature_by_args(
111112
.collect::<Vec<_>>(),
112113
};
113114

114-
let exp_len = expr_types.len();
115-
if exp_len == 0 {
115+
if expr_len == 0 {
116116
for overload in overloads {
117117
let param_len = overload.get_params().len();
118118
if param_len == 0 {
@@ -122,7 +122,7 @@ pub fn resolve_signature_by_args(
122122
}
123123

124124
let mut best_match_result = need_resolve_funcs[0].clone().unwrap();
125-
for arg_index in 0..exp_len {
125+
for arg_index in 0..expr_len {
126126
let mut current_match_result = ParamMatchResult::NotMatch;
127127
for i in 0..need_resolve_funcs.len() {
128128
let opt_func = &need_resolve_funcs[i];
@@ -131,7 +131,7 @@ pub fn resolve_signature_by_args(
131131
}
132132
let func = opt_func.as_ref().unwrap();
133133
let param_len = func.get_params().len();
134-
if param_len < arg_count {
134+
if param_len < arg_count && !is_func_last_param_variadic(func) {
135135
need_resolve_funcs[i] = None;
136136
continue;
137137
}
@@ -186,10 +186,11 @@ pub fn resolve_signature_by_args(
186186
continue;
187187
}
188188

189-
if match_result > ParamMatchResult::AnyMatch {
190-
if param_index + 1 == func.get_params().len() {
191-
return Ok(func.clone());
192-
}
189+
if match_result > ParamMatchResult::AnyMatch
190+
&& arg_index + 1 == expr_len
191+
&& param_index + 1 == func.get_params().len()
192+
{
193+
return Ok(func.clone());
193194
}
194195
}
195196

@@ -210,7 +211,7 @@ pub fn resolve_signature_by_args(
210211
_ => {}
211212
}
212213

213-
let start_param_index = exp_len;
214+
let start_param_index = expr_len;
214215
let mut max_param_len = 0;
215216
for opt_func in &rest_need_resolve_funcs {
216217
if let Some(func) = opt_func {
@@ -278,10 +279,11 @@ pub fn resolve_signature_by_args(
278279
continue;
279280
}
280281

281-
if match_result >= ParamMatchResult::AnyMatch {
282-
if param_index + 1 == func.get_params().len() {
283-
return Ok(func.clone());
284-
}
282+
if match_result >= ParamMatchResult::AnyMatch
283+
&& i + 1 == rest_len
284+
&& param_index + 1 == func.get_params().len()
285+
{
286+
return Ok(func.clone());
285287
}
286288
}
287289

@@ -293,6 +295,14 @@ pub fn resolve_signature_by_args(
293295
Ok(best_match_result)
294296
}
295297

298+
fn is_func_last_param_variadic(func: &LuaFunctionType) -> bool {
299+
if let Some(last_param) = func.get_params().last() {
300+
last_param.0 == "..."
301+
} else {
302+
false
303+
}
304+
}
305+
296306
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
297307
enum ParamMatchResult {
298308
NotMatch,

0 commit comments

Comments
 (0)