Skip to content

Commit d7865ec

Browse files
committed
Improve inference for anonymous functions
1 parent 1f211d1 commit d7865ec

2 files changed

Lines changed: 15 additions & 11 deletions

File tree

lib/elixir/lib/module/types/expr.ex

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ defmodule Module.Types.Expr do
337337

338338
{acc, context} =
339339
of_clauses_fun(clauses, domain, @pending, :fn, stack, context, [], fn
340-
args_types, body, acc ->
340+
trees, body, context, acc ->
341+
args_types = Pattern.of_domain(trees, stack, context)
341342
add_inferred(acc, args_types, body)
342343
end)
343344

@@ -719,7 +720,7 @@ defmodule Module.Types.Expr do
719720
defp dynamic_unless_static({type, context}, %{mode: _}), do: {dynamic(type), context}
720721

721722
defp of_clauses(clauses, domain, expected, clause_info, stack, context, acc) do
722-
fun = fn _args_types, result, acc -> union(result, acc) end
723+
fun = fn _args_types, result, _context, acc -> union(result, acc) end
723724
of_clauses_fun(clauses, domain, expected, clause_info, stack, context, acc, fun)
724725
end
725726

@@ -750,24 +751,24 @@ defmodule Module.Types.Expr do
750751
{trees, precise?, context}
751752
end
752753

753-
args_types =
754-
Enum.map(trees, fn {tree, _, _} ->
755-
Pattern.of_pattern_tree(tree, stack, context)
756-
end)
757-
758754
{previous, context} =
759755
if context.failed do
760756
{previous, context}
761757
else
762-
upper_types = Enum.map(args_types, &upper_bound/1)
758+
args_types =
759+
Enum.map(trees, fn {tree, _, _} ->
760+
tree
761+
|> Pattern.of_pattern_tree(stack, context)
762+
|> upper_bound()
763+
end)
763764

764765
cond do
765766
stack.mode != :infer and previous != [] and
766-
Pattern.args_subtype?(upper_types, previous) ->
767+
Pattern.args_subtype?(args_types, previous) ->
767768
{previous, Pattern.redundant_warn(clause, previous, stack, context)}
768769

769770
precise? ->
770-
{[upper_types | previous], context}
771+
{[args_types | previous], context}
771772

772773
true ->
773774
{previous, context}
@@ -776,7 +777,7 @@ defmodule Module.Types.Expr do
776777

777778
{result, context} = of_expr(body, expected, body, stack, context)
778779

779-
{fun.(args_types, result, acc), previous,
780+
{fun.(trees, result, context, acc), previous,
780781
context |> set_failed(failed?) |> Of.reset_vars(original)}
781782
end)
782783

lib/elixir/test/elixir/module/types/expr_test.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ defmodule Module.Types.ExprTest do
180180
)
181181
)
182182
)
183+
184+
assert typecheck!(fn x -> Integer.to_string(x) end) ==
185+
fun([integer()], dynamic(binary()))
183186
end
184187

185188
test "application" do

0 commit comments

Comments
 (0)