Skip to content

Commit 0efa5d0

Browse files
author
efve.zff
committed
fix: resolve overload before generic constraint check, to avoid false positives from merged parameter types
1 parent 2f9cb6d commit 0efa5d0

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

crates/emmylua_code_analysis/src/diagnostic/test/generic_constraint_mismatch_test.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,4 +377,33 @@ mod test {
377377
"#
378378
));
379379
}
380+
381+
#[test]
382+
fn test_overload_generic_constraint_merged_params() {
383+
// When a generic signature has overloads, the merged main signature
384+
// unions parameter types from all overloads. Constraint checks must
385+
// run against the resolved overload, not the merged signature.
386+
let mut ws = VirtualWorkspace::new();
387+
ws.def_file(
388+
"mylib.lua",
389+
r#"
390+
---@meta mylib
391+
local M = {}
392+
393+
---@generic T: table
394+
---@overload fun(a: string, b: T?): T
395+
---@overload fun(a: string, b: integer, c: T?): T
396+
function M.decode(a, b_or_c, c) end
397+
398+
return M
399+
"#,
400+
);
401+
assert!(ws.check_code_for(
402+
DiagnosticCode::GenericConstraintMismatch,
403+
r#"
404+
local m = require("mylib")
405+
local ret = m.decode("x", 42)
406+
"#
407+
));
408+
}
380409
}

crates/emmylua_code_analysis/src/semantic/generic/call_constraint.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,15 @@ fn infer_call_doc_function(
206206
.get_db()
207207
.get_signature_index()
208208
.get(&signature_id)?;
209+
if !signature.overloads.is_empty() {
210+
// When a signature has overloads, `to_doc_func_type()` merges all overload
211+
// parameter types into unions on the main signature. This produces incorrect
212+
// types for generic constraint checking (e.g. a merged `T | nil | integer`
213+
// would falsely trigger a constraint mismatch).
214+
// Instead, resolve the actual overload that matches the call arguments,
215+
// so that constraint checking runs against the correct parameter types.
216+
return semantic_model.infer_call_expr_func(call_expr.clone(), None);
217+
}
209218
Some(signature.to_doc_func_type())
210219
}
211220
LuaType::DocFunction(func) => Some(func),

0 commit comments

Comments
 (0)