Skip to content

Commit f43b476

Browse files
committed
Use standardized return type
1 parent 7452530 commit f43b476

File tree

2 files changed

+90
-74
lines changed

2 files changed

+90
-74
lines changed

lib/elixir/lib/module/types/of.ex

Lines changed: 45 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,24 @@ defmodule Module.Types.Of do
321321

322322
for {mod, fun, clauses} <- [
323323
{:erlang, :binary_to_integer, [{[binary()], integer()}]},
324-
{:erlang, :integer_to_binary, [{[integer()], binary()}]}
324+
{:erlang, :integer_to_binary, [{[integer()], binary()}]},
325+
326+
# TODO: Replace term()/dynamic() by parametric types
327+
{:erlang, :hd, [{[non_empty_list(term(), term())], dynamic()}]},
328+
{:erlang, :tl, [{[non_empty_list(term(), term())], dynamic()}]},
329+
{:erlang, :delete_element,
330+
[{[integer(), open_tuple([], term())], dynamic(open_tuple([], term()))}]},
331+
{:erlang, :element, [{[integer(), open_tuple([], term())], dynamic()}]},
332+
{:erlang, :insert_element,
333+
[{[integer(), open_tuple([], term()), term()], dynamic(open_tuple([], term()))}]}
325334
] do
326335
[{args, _return} | _others] = clauses
327336

328-
defp strong_remote(unquote(mod), unquote(fun), unquote(length(args))),
337+
defp remote(unquote(mod), unquote(fun), unquote(length(args))),
329338
do: unquote(Macro.escape(clauses))
330339
end
331340

332-
defp strong_remote(_mod, _fun, _arity), do: []
341+
defp remote(_mod, _fun, _arity), do: []
333342

334343
@doc """
335344
Checks a module is a valid remote.
@@ -353,7 +362,7 @@ defmodule Module.Types.Of do
353362
if Keyword.get(meta, :runtime_module, false) do
354363
{:none, context}
355364
else
356-
case strong_remote(module, fun, arity) do
365+
case remote(module, fun, arity) do
357366
[] -> {:none, check_export(module, fun, arity, meta, stack, context)}
358367
clauses -> {{:strong, clauses}, context}
359368
end
@@ -368,6 +377,9 @@ defmodule Module.Types.Of do
368377
{_optional?, value_type} ->
369378
{value_type, context}
370379

380+
:badtuple ->
381+
{error_type(), badapply_error(expr, [integer(), tuple], stack, context)}
382+
371383
reason ->
372384
{error_type(), error({reason, expr, tuple, index - 1, context}, meta, stack, context)}
373385
end
@@ -386,6 +398,9 @@ defmodule Module.Types.Of do
386398
value_type when is_descr(value_type) ->
387399
{value_type, context}
388400

401+
:badtuple ->
402+
{error_type(), badapply_error(expr, [integer(), tuple, value], stack, context)}
403+
389404
reason ->
390405
{error_type(), error({reason, expr, tuple, index - 2, context}, meta, stack, context)}
391406
end
@@ -397,6 +412,9 @@ defmodule Module.Types.Of do
397412
value_type when is_descr(value_type) ->
398413
{value_type, context}
399414

415+
:badtuple ->
416+
{error_type(), badapply_error(expr, [integer(), tuple], stack, context)}
417+
400418
reason ->
401419
{error_type(), error({reason, expr, tuple, index - 1, context}, meta, stack, context)}
402420
end
@@ -412,8 +430,8 @@ defmodule Module.Types.Of do
412430
{_, value_type} ->
413431
{value_type, context}
414432

415-
reason ->
416-
{error_type(), error({reason, expr, list, context}, elem(expr, 1), stack, context)}
433+
:badnonemptylist ->
434+
{error_type(), badapply_error(expr, [list], stack, context)}
417435
end
418436
end
419437

@@ -422,8 +440,8 @@ defmodule Module.Types.Of do
422440
{_, value_type} ->
423441
{value_type, context}
424442

425-
reason ->
426-
{error_type(), error({reason, expr, list, context}, elem(expr, 1), stack, context)}
443+
:badnonemptylist ->
444+
{error_type(), badapply_error(expr, [list], stack, context)}
427445
end
428446
end
429447

@@ -705,48 +723,6 @@ defmodule Module.Types.Of do
705723
}
706724
end
707725

708-
def format_diagnostic({:badnonemptylist, expr, type, context}) do
709-
traces = collect_traces(expr, context)
710-
711-
%{
712-
details: %{typing_traces: traces},
713-
message:
714-
IO.iodata_to_binary([
715-
"""
716-
expected a non-empty list in #{format_mfa(expr)}:
717-
718-
#{expr_to_string(expr) |> indent(4)}
719-
720-
but got type:
721-
722-
#{to_quoted_string(type) |> indent(4)}
723-
""",
724-
format_traces(traces)
725-
])
726-
}
727-
end
728-
729-
def format_diagnostic({:badtuple, expr, type, _index, context}) do
730-
traces = collect_traces(expr, context)
731-
732-
%{
733-
details: %{typing_traces: traces},
734-
message:
735-
IO.iodata_to_binary([
736-
"""
737-
expected a tuple in #{format_mfa(expr)}:
738-
739-
#{expr_to_string(expr) |> indent(4)}
740-
741-
but got type:
742-
743-
#{to_quoted_string(type) |> indent(4)}
744-
""",
745-
format_traces(traces)
746-
])
747-
}
748-
end
749-
750726
def format_diagnostic({:badindex, expr, type, index, context}) do
751727
traces = collect_traces(expr, context)
752728

@@ -794,23 +770,24 @@ defmodule Module.Types.Of do
794770

795771
def format_diagnostic({:badapply, expr, args_types, clauses, context}) do
796772
traces = collect_traces(expr, context)
773+
{{:., _, [mod, fun]}, _, args} = expr
797774

798775
%{
799776
details: %{typing_traces: traces},
800777
message:
801778
IO.iodata_to_binary([
802779
"""
803-
incompatible types given to #{format_mfa(expr)}:
780+
incompatible types given to #{format_mfa(mod, fun, args)}:
804781
805782
#{expr_to_string(expr) |> indent(4)}
806783
807784
expected types:
808785
809-
#{clauses_args_to_quoted_string(clauses) |> indent(4)}
786+
#{clauses_args_to_quoted_string(mod, fun, clauses) |> indent(4)}
810787
811788
but got types:
812789
813-
#{args_to_quoted_string(args_types) |> indent(4)}
790+
#{args_to_quoted_string(mod, fun, args_types) |> indent(4)}
814791
""",
815792
format_traces(traces)
816793
])
@@ -936,15 +913,22 @@ defmodule Module.Types.Of do
936913
match?({{:., _, [var, _fun]}, _, _args} when is_var(var), expr)
937914
end
938915

939-
defp clauses_args_to_quoted_string([{args, _return}]) do
940-
args_to_quoted_string(args)
916+
defp badapply_error({{:., _, [mod, fun]}, meta, _} = expr, args_types, stack, context) do
917+
clauses = remote(mod, fun, length(args_types))
918+
error({:badapply, expr, args_types, clauses, context}, meta, stack, context)
919+
end
920+
921+
defp clauses_args_to_quoted_string(mod, fun, [{args, _return}]) do
922+
args_to_quoted_string(mod, fun, args)
941923
end
942924

943-
defp args_to_quoted_string([arg]) do
925+
defp args_to_quoted_string(_mod, _fun, [arg]) do
944926
to_quoted_string(arg)
945927
end
946928

947-
defp args_to_quoted_string(args) do
929+
defp args_to_quoted_string(mod, fun, args) do
930+
{_mod, _fun, args} = :elixir_rewrite.erl_to_ex(mod, fun, args)
931+
948932
{:_, [], Enum.map(args, &to_quoted/1)}
949933
|> Code.Formatter.to_algebra()
950934
|> Inspect.Algebra.format(98)
@@ -960,6 +944,10 @@ defmodule Module.Types.Of do
960944
end
961945

962946
defp format_mfa({{:., _, [mod, fun]}, _, args}) do
947+
format_mfa(mod, fun, args)
948+
end
949+
950+
defp format_mfa(mod, fun, args) do
963951
{mod, fun, args} = :elixir_rewrite.erl_to_ex(mod, fun, args)
964952
Exception.format_mfa(mod, fun, length(args))
965953
end

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

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,31 @@ defmodule Module.Types.ExprTest do
4848
assert typewarn!(hd([])) ==
4949
{dynamic(),
5050
~l"""
51-
expected a non-empty list in Kernel.hd/1:
51+
incompatible types given to Kernel.hd/1:
5252
5353
hd([])
5454
55-
but got type:
55+
expected types:
56+
57+
non_empty_list(term(), term())
58+
59+
but got types:
5660
5761
empty_list()
5862
"""}
5963

6064
assert typewarn!(hd(123)) ==
6165
{dynamic(),
6266
~l"""
63-
expected a non-empty list in Kernel.hd/1:
67+
incompatible types given to Kernel.hd/1:
6468
6569
hd(123)
6670
67-
but got type:
71+
expected types:
72+
73+
non_empty_list(term(), term())
74+
75+
but got types:
6876
6977
integer()
7078
"""}
@@ -79,23 +87,31 @@ defmodule Module.Types.ExprTest do
7987
assert typewarn!(tl([])) ==
8088
{dynamic(),
8189
~l"""
82-
expected a non-empty list in Kernel.tl/1:
90+
incompatible types given to Kernel.tl/1:
8391
8492
tl([])
8593
86-
but got type:
94+
expected types:
95+
96+
non_empty_list(term(), term())
97+
98+
but got types:
8799
88100
empty_list()
89101
"""}
90102

91103
assert typewarn!(tl(123)) ==
92104
{dynamic(),
93105
~l"""
94-
expected a non-empty list in Kernel.tl/1:
106+
incompatible types given to Kernel.tl/1:
95107
96108
tl(123)
97109
98-
but got type:
110+
expected types:
111+
112+
non_empty_list(term(), term())
113+
114+
but got types:
99115
100116
integer()
101117
"""}
@@ -322,13 +338,17 @@ defmodule Module.Types.ExprTest do
322338
assert typewarn!([<<x::integer>>], elem(x, 0)) ==
323339
{dynamic(),
324340
~l"""
325-
expected a tuple in Kernel.elem/2:
341+
incompatible types given to Kernel.elem/2:
326342
327343
elem(x, 0)
328344
329-
but got type:
345+
expected types:
330346
331-
integer()
347+
integer(), {...}
348+
349+
but got types:
350+
351+
integer(), integer()
332352
333353
where "x" was given the type:
334354
@@ -365,13 +385,17 @@ defmodule Module.Types.ExprTest do
365385
assert typewarn!([<<x::integer>>], Tuple.insert_at(x, 0, "foo")) ==
366386
{dynamic(),
367387
~l"""
368-
expected a tuple in Tuple.insert_at/3:
388+
incompatible types given to Tuple.insert_at/3:
369389
370390
Tuple.insert_at(x, 0, "foo")
371391
372-
but got type:
392+
expected types:
373393
374-
integer()
394+
integer(), {...}, term()
395+
396+
but got types:
397+
398+
integer(), integer(), binary()
375399
376400
where "x" was given the type:
377401
@@ -402,13 +426,17 @@ defmodule Module.Types.ExprTest do
402426
assert typewarn!([<<x::integer>>], Tuple.delete_at(x, 0)) ==
403427
{dynamic(),
404428
~l"""
405-
expected a tuple in Tuple.delete_at/2:
429+
incompatible types given to Tuple.delete_at/2:
406430
407431
Tuple.delete_at(x, 0)
408432
409-
but got type:
433+
expected types:
410434
411-
integer()
435+
integer(), {...}
436+
437+
but got types:
438+
439+
integer(), integer()
412440
413441
where "x" was given the type:
414442

0 commit comments

Comments
 (0)