Gradualizer icon indicating copy to clipboard operation
Gradualizer copied to clipboard

Crash in update_map_type

Open lukaszsamson opened this issue 5 years ago • 2 comments

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

lukaszsamson avatar Feb 14 '20 19:02 lukaszsamson

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...

zuiderkwast avatar Feb 14 '20 20:02 zuiderkwast

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"]}
]}.

belltoy avatar May 07 '21 12:05 belltoy

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 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...

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.

erszcz avatar Nov 14 '22 13:11 erszcz