Improve error message for invalid default arguments
This commit is contained in:
@@ -785,7 +785,7 @@ defmodule Module.Types.Apply do
|
||||
def format_diagnostic({:badlocal, expr, args_types, domain, clauses, context}) do
|
||||
traces = collect_traces(expr, context)
|
||||
converter = &Function.identity/1
|
||||
{fun, _, _} = expr
|
||||
{fun, meta, _} = expr
|
||||
|
||||
explanation =
|
||||
empty_arg_reason(args_types) ||
|
||||
@@ -794,16 +794,29 @@ defmodule Module.Types.Apply do
|
||||
#{clauses_args_to_quoted_string(clauses, converter)}
|
||||
"""
|
||||
|
||||
%{
|
||||
details: %{typing_traces: traces},
|
||||
message:
|
||||
IO.iodata_to_binary([
|
||||
banner =
|
||||
case fun == :super && meta[:default] && meta[:super] do
|
||||
{_kind, fun} ->
|
||||
"""
|
||||
incompatible types given as default arguments to #{fun}/#{length(args_types)}:
|
||||
"""
|
||||
|
||||
_ ->
|
||||
"""
|
||||
incompatible types given to #{fun}/#{length(args_types)}:
|
||||
|
||||
#{expr_to_string(expr) |> indent(4)}
|
||||
|
||||
given types:
|
||||
"""
|
||||
end
|
||||
|
||||
%{
|
||||
details: %{typing_traces: traces},
|
||||
message:
|
||||
IO.iodata_to_binary([
|
||||
banner,
|
||||
"""
|
||||
|
||||
#{args_to_quoted_string(args_types, domain, converter) |> indent(4)}
|
||||
|
||||
|
||||
@@ -314,7 +314,7 @@ unpack_defaults(Kind, Meta, Name, Args, S, E) ->
|
||||
unpack_expanded(Kind, Meta, Name, [{'\\\\', DefaultMeta, [Expr, _]} | T] = List, VersionOffset, Acc, Clauses) ->
|
||||
Base = match_defaults(Acc, length(Acc) + VersionOffset, []),
|
||||
{Args, Invoke} = extract_defaults(List, length(Base) + VersionOffset, [], []),
|
||||
Clause = {Meta, Base ++ Args, [], {super, [{super, {Kind, Name}} | DefaultMeta], Base ++ Invoke}},
|
||||
Clause = {Meta, Base ++ Args, [], {super, [{super, {Kind, Name}}, {default, true} | DefaultMeta], Base ++ Invoke}},
|
||||
unpack_expanded(Kind, Meta, Name, T, VersionOffset, [Expr | Acc], [Clause | Clauses]);
|
||||
unpack_expanded(Kind, Meta, Name, [H | T], VersionOffset, Acc, Clauses) ->
|
||||
unpack_expanded(Kind, Meta, Name, T, VersionOffset, [H | Acc], Clauses);
|
||||
|
||||
@@ -244,6 +244,39 @@ defmodule Module.Types.IntegrationTest do
|
||||
assert_no_warnings(files)
|
||||
end
|
||||
|
||||
test "incompatible default argument" do
|
||||
files = %{
|
||||
"a.ex" => """
|
||||
defmodule A do
|
||||
def ok(x = :ok \\\\ nil) do
|
||||
x
|
||||
end
|
||||
end
|
||||
"""
|
||||
}
|
||||
|
||||
warnings = [
|
||||
~S"""
|
||||
warning: incompatible types given as default arguments to ok/1:
|
||||
|
||||
-nil-
|
||||
|
||||
but expected one of:
|
||||
|
||||
dynamic(:ok)
|
||||
|
||||
typing violation found at:
|
||||
│
|
||||
2 │ def ok(x = :ok \\ nil) do
|
||||
│ ~
|
||||
│
|
||||
└─ a.ex:2:18: A.ok/0
|
||||
"""
|
||||
]
|
||||
|
||||
assert_warnings(files, warnings)
|
||||
end
|
||||
|
||||
test "returns diagnostics with source and file" do
|
||||
files = %{
|
||||
"a.ex" => """
|
||||
|
||||
Reference in New Issue
Block a user