Skip to content

Commit 3b763c6

Browse files
committed
fix(code-analysis): keep overload returns wide on unknown args
1 parent c058e3d commit 3b763c6

2 files changed

Lines changed: 44 additions & 3 deletions

File tree

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,36 @@ mod test {
261261
assert_eq!(ws.humanize_type(result_ty), "string");
262262
}
263263

264+
#[test]
265+
fn test_apply_return_infer_keeps_same_arity_overload_returns_when_tail_is_unknown() {
266+
let mut ws = VirtualWorkspace::new();
267+
ws.def(
268+
r#"
269+
---@generic A, B, R
270+
---@param f fun(x: A, y: B): R
271+
---@param x A
272+
---@param y B
273+
---@return R
274+
local function apply2(f, x, y)
275+
return f(x, y)
276+
end
277+
278+
---@overload fun(x: integer, y: number): number
279+
---@param x integer
280+
---@param y string
281+
---@return string
282+
local function run(x, y) end
283+
284+
local source ---@type table
285+
286+
result = apply2(run, 1, source.missing)
287+
"#,
288+
);
289+
290+
let result_ty = ws.expr_ty("result");
291+
assert_eq!(result_ty, ws.ty("number|string"));
292+
}
293+
264294
#[test]
265295
fn test_union_call_ignores_non_matching_generic_callable_member() {
266296
let mut ws = VirtualWorkspace::new();

crates/emmylua_code_analysis/src/semantic/generic/instantiate_type/instantiate_func_generic.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,19 @@ fn infer_callable_return_from_arg_types(
216216
} else {
217217
&preferred_overloads
218218
};
219+
let unresolved_arg_match = overloads_to_resolve.len() > 1
220+
&& call_arg_types
221+
.iter()
222+
.any(|arg_type| arg_type.is_any() || arg_type.is_unknown());
219223

220-
member_returns.push(
224+
member_returns.push(if unresolved_arg_match {
225+
LuaType::from_vec(
226+
overloads_to_resolve
227+
.iter()
228+
.map(|callable| callable.get_ret().clone())
229+
.collect(),
230+
)
231+
} else {
221232
resolve_signature_by_args(
222233
context.db,
223234
overloads_to_resolve,
@@ -226,8 +237,8 @@ fn infer_callable_return_from_arg_types(
226237
None,
227238
)
228239
.map(|callable| callable.get_ret().clone())
229-
.unwrap_or_else(|_| fallback_return_from_overloads(context.db, overloads)),
230-
);
240+
.unwrap_or_else(|_| fallback_return_from_overloads(context.db, overloads))
241+
});
231242
}
232243
if member_returns.is_empty() {
233244
return Ok(if fallback_on_no_match {

0 commit comments

Comments
 (0)