Gradualizer
Gradualizer copied to clipboard
Crash in update_map_type
When run on elixir-ls project, gradualizer crashes in typechecker:update_map_type/2
** (FunctionClauseError) no function clause matching in :typechecker.update_map_type/2
The following arguments were given to :typechecker.update_map_type/2:
# 1
{:type, 0, :union, [{:type, 0, :any, []}, {:type, 0, :map, [{:type, 0, :map_field_exact, [{:atom, 0, :kind}, {:atom, 0, :keyword}]}, {:type, 0, :map_field_exact, [{:atom, 0, :priority}, {:integer, 0, 8}]}, {:type, 0, :map_field_assoc, [{:type, 0, :any, []}, {:type, 0, :any, []}]}]}]}
# 2
[{:type, 0, :map_field_exact, [{:atom, 0, :insert_text}, {:type, 0, :any, []}]}, {:type, 0, :map_field_exact, [{:atom, 0, :kind}, {:atom, 0, :snippet}]}, {:type, 0, :map_field_exact, [{:atom, 0, :label}, {:type, 0, :any, []}]}]
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:2883: :typechecker.update_map_type/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:1566: :typechecker.do_type_check_expr/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:1394: :typechecker.type_check_expr/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:3163: :typechecker.infer_clause/2
(stdlib 3.11.2) lists.erl:1239: :lists.map/2
(stdlib 3.11.2) lists.erl:1239: :lists.map/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:3143: :typechecker.infer_clauses/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:1420: :typechecker.do_type_check_expr/2
** (FunctionClauseError) no function clause matching in :typechecker.update_map_type/2
The following arguments were given to :typechecker.update_map_type/2:
# 1
{:type, 0, :union, [{:type, 0, :any, []}, {:type, 0, :map, [{:type, 0, :map_field_exact, [{:atom, 0, :root_uri}, {:type, 0, :any, []}]}, {:type, 0, :map_field_assoc, [{:type, 0, :any, []}, {:type, 0, :any, []}]}]}]}
# 2
[{:type, 0, :map_field_exact, [{:atom, 0, :client_capabilities}, {:type, 0, :any, []}]}]
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:2883: :typechecker.update_map_type/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:1566: :typechecker.do_type_check_expr/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:1394: :typechecker.type_check_expr/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:1407: :typechecker.do_type_check_expr/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:1394: :typechecker.type_check_expr/2
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:3036: :typechecker.type_check_block_in/3
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:3037: :typechecker.type_check_block_in/3
(gradualizer 0.1.0) /Users/vscode-elixir-ls/elixir-ls/deps/gradualizer/src/typechecker.erl:3257: :typechecker.check_clause/4
Thanks for the report! Update_map_type is hanling an expression on the form Map#{update := fields}
and here the expected type of this expression appears to be a union on the form any() | #{some := map_type}
, which is unandled...
Additional error info:
[{typechecker,update_map_type,
[{type,0,union,[{var,0,'AccOut'},{var,0,'Init'}]},
[{type,0,map_field_assoc,
[{var,0,'Key'},
{user_type,[{file,"myapp_utils.erl"},{location,0}],
maybe,
[{type,0,binary,[]}]}]}]],
[{file,".../_build/default/plugins/gradualizer/src/typechecker.erl"},
{line,2858}]},
BTW, the exclude
option did not work neither:
{gradualizer_opts, [
{exclude, ["path/to/myapp_utils.erl"]}
]}.
Having run mix gradient
on ElixirLS I get some warnings, but Gradient and Gradualizer do not crash.
update_map_type
is handling an expression of the formMap#{update := fields}
and here the expected type of this expression appears to be a union on the formany() | #{some := map_type}
, which is unandled...
This is handled since 0b8e6a8fe1100b8e11cd6f822c9093ee76959eaa, which confirms my result of running mix gradient
.
The warnings returned are of various quality. After quickly glancing over them, I can certainly see some valid ones, some false positives, and some which ought to be handled by Gradient, but aren't yet (e.g. the Elixir match?
macro).
I think this ticket can be closed, since the original issue is now addressed.