Skip to content

Commit 60f7d00

Browse files
committed
More progress
1 parent f405d31 commit 60f7d00

File tree

4 files changed

+47
-9
lines changed

4 files changed

+47
-9
lines changed

lib/elixir/lib/module/types/apply.ex

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,6 @@ defmodule Module.Types.Apply do
472472
Returns the type of a remote capture.
473473
"""
474474
def remote_capture(modules, fun, arity, meta, stack, context) do
475-
# TODO: Do we check when the union of functions is invalid?
476475
# TODO: Deal with :infer types
477476
if stack.mode == :traversal or modules == [] do
478477
{dynamic(fun(arity)), context}
@@ -829,14 +828,17 @@ defmodule Module.Types.Apply do
829828

830829
message =
831830
case reason do
832-
# TODO: Return the domain here
833-
{:badarg, _} ->
831+
{:badarg, domain} ->
834832
"""
835-
expected a #{length(args_types)}-arity function on call:
833+
incompatible types given on function application:
836834
837835
#{expr_to_string(expr) |> indent(4)}
838836
839-
but got type:
837+
given types:
838+
839+
#{args_to_quoted_string(args_types, domain, &Function.identity/1) |> indent(4)}
840+
841+
but function has type:
840842
841843
#{to_quoted_string(fun_type) |> indent(4)}
842844
"""

lib/elixir/lib/module/types/helpers.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,15 @@ defmodule Module.Types.Helpers do
324324
{{:., _, [mod, fun]}, meta, args} ->
325325
erl_to_ex(mod, fun, args, meta)
326326

327+
{:&, amp_meta, [{:/, slash_meta, [{{:., dot_meta, [mod, fun]}, call_meta, []}, arity]}]} ->
328+
{mod, fun} =
329+
case :elixir_rewrite.erl_to_ex(mod, fun, arity) do
330+
{mod, fun} -> {mod, fun}
331+
false -> {mod, fun}
332+
end
333+
334+
{:&, amp_meta, [{:/, slash_meta, [{{:., dot_meta, [mod, fun]}, call_meta, []}, arity]}]}
335+
327336
{:case, meta, [expr, [do: clauses]]} = case ->
328337
if meta[:type_check] == :expr do
329338
case clauses do

lib/elixir/src/elixir_rewrite.erl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@
4444
inner_rewrite(erl_to_ex, _Meta, ErlMod, ErlFun, ErlArgs) -> {ExMod, ExFun, ExArgs, fun(ErlArgs) -> ExArgs end}
4545
).
4646

47-
erl_to_ex(Mod, Fun, Args) ->
47+
erl_to_ex(Mod, Fun, Args) when is_list(Args) ->
4848
case inner_inline(erl_to_ex, Mod, Fun, length(Args)) of
4949
false -> inner_rewrite(erl_to_ex, [], Mod, Fun, Args);
5050
{ExMod, ExFun} -> {ExMod, ExFun, Args, fun identity/1}
51-
end.
51+
end;
52+
53+
erl_to_ex(Mod, Fun, Arity) when is_integer(Arity) ->
54+
inner_inline(erl_to_ex, Mod, Fun, Arity).
5255

53-
%% Inline rules
56+
%% Inline rules
5457
%%
5558
%% Inline rules are straightforward, they keep the same
5659
%% number and order of arguments and show up on captures.

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ defmodule Module.Types.ExprTest do
139139
) == dynamic(fun(2))
140140
end
141141

142-
test "incompatible" do
142+
test "bad function" do
143143
assert typeerror!([%x{}, a1, a2], x.(a1, a2)) == ~l"""
144144
expected a 2-arity function on call:
145145
@@ -156,6 +156,30 @@ defmodule Module.Types.ExprTest do
156156
%x{}
157157
"""
158158
end
159+
160+
test "bad arity" do
161+
assert typeerror!([a1, a2], (&String.to_integer/1).(a1, a2)) == ~l"""
162+
expected a 2-arity function on call:
163+
164+
(&String.to_integer/1).(a1, a2)
165+
166+
but got function with arity 1:
167+
168+
(binary() -> integer())
169+
"""
170+
end
171+
172+
test "bad argument" do
173+
assert typeerror!([%a{}], (&String.to_integer/1).(a)) == ~l"""
174+
expected a 2-arity function on call:
175+
176+
(&String.to_integer/1).(a1, a2)
177+
178+
but got function with arity 1:
179+
180+
(binary() -> integer())
181+
"""
182+
end
159183
end
160184

161185
describe "remotes" do

0 commit comments

Comments
 (0)