File tree Expand file tree Collapse file tree
crates/emmylua_code_analysis/src
semantic/generic/instantiate_type Expand file tree Collapse file tree Original file line number Diff line number Diff 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 ( ) ;
Original file line number Diff line number Diff 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 {
You can’t perform that action at this time.
0 commit comments