dialyxir
dialyxir copied to clipboard
CaseClauseError running with --force-check
Environment
$ elixir --version
Erlang/OTP 21 [erts-10.2.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Elixir 1.8.1 (compiled with Erlang/OTP 21)
$ cat mix.lock | grep dialyxir
"dialyxir": {:hex, :dialyxir, "1.0.0-rc.4", "71b42f5ee1b7628f3e3a6565f4617dfb02d127a0499ab3e72750455e986df001", [:mix], [{:erlex, "~> 0.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"}
Current behavior
Running with --force-check
causes the following problem:
$ mix dialyzer --force-check
==> things
Compiling 2 files (.ex)
Generated things app
==> persistent
Compiling 6 files (.ex)
In an Umbrella child, not checking PLT...
Starting Dialyzer
[
check_plt: true,
init_plt: '/home/user/.project/_build/dev/dialyxir_erlang-21.2.5_elixir-1.8.1_deps-dev.plt',
files_rec: ['/home/user/.project/_build/dev/lib/persistent/ebin'],
warnings: [:unknown]
]
** (CaseClauseError) no case clause matching: {{:nocatch, {:dialyzer_error, [78, 111, 116, 32, 97, 32, 114, 101, 103, 117, 108, 97, 114, 32, 102, 105, 108, 101, 58, 32, '/home/user/.project/_build/dev/lib/things/ebin/Elixir.AAA.beam', 10]}}, [{:dialyzer_plt, :compute_md5_from_file, 1, [file: 'dialyzer_plt.erl', line: 543]}, {:dialyzer_plt, :compute_new_md5_1, 3, [file: 'dialyzer_plt.erl', line: 509]}, {:dialyzer_plt, :check_plt1, 3, [file: 'dialyzer_plt.erl', line: 479]}, {:dialyzer_plt, :"-subproc/1-fun-0-", 1, [file: 'dialyzer_plt.erl', line: 603]}]}
dialyzer_cl.erl:249: :dialyzer_cl.check_plt/3
dialyzer_cl.erl:182: :dialyzer_cl.plt_common/3
dialyzer.erl:94: anonymous fn/1 in :dialyzer.cl_check_init/1
dialyzer.erl:236: :dialyzer.doit/1
dialyzer.erl:172: :dialyzer.check_init/1
dialyzer.erl:159: :dialyzer.run/1
(stdlib) timer.erl:181: :timer.tc/2
lib/dialyxir/dialyzer.ex:39: Dialyxir.Dialyzer.Runner.run/2
Expected behavior
It should check the PLT, instead of giving this error.
Making the error readable:
path =
{{
:nocatch,
{
:dialyzer_error,
[78, 111, 116, 32, 97, 32, 114, 101, 103, 117, 108, 97, 114, 32, 102, 105, 108, 101, 58, 32, '/home/user/.project/_build/dev/lib/things/ebin/Elixir.AAA.beam', 10]
}
}, [
{:dialyzer_plt, :compute_md5_from_file, 1, [file: 'dialyzer_plt.erl', line: 543]},
{:dialyzer_plt, :compute_new_md5_1, 3, [file: 'dialyzer_plt.erl', line: 509]},
{:dialyzer_plt, :check_plt1, 3, [file: 'dialyzer_plt.erl', line: 479]},
{:dialyzer_plt, :"-subproc/1-fun-0-", 1, [file: 'dialyzer_plt.erl', line: 603]}
]}
|> elem(0)
|> elem(1)
|> elem(1)
:io.format("~ts", [path])
$ elixir error.exs
Not a regular file: /home/user/.project/_build/dev/lib/things/ebin/Elixir.AAA.beam
The error is thrown within this function in dialyzer_plt.erl
:
compute_md5_from_file(File) ->
case beam_lib:all_chunks(File) of
{ok, _, Chunks} ->
%% We cannot use beam_lib:md5 because it does not consider
%% the debug_info chunk, where typespecs are likely stored.
%% So we consider almost all chunks except the useless ones.
Filtered = [[ID, Chunk] || {ID, Chunk} <- Chunks, ID =/= "CInf", ID =/= "Docs"],
erlang:md5(lists:sort(Filtered));
{error, beam_lib, {file_error, _, enoent}} ->
Msg = io_lib:format("Not a regular file: ~ts\n", [File]),
throw({dialyzer_error, Msg}); % <-------------------------------- Here.
{error, beam_lib, _} ->
Msg = io_lib:format("Could not compute MD5 for .beam: ~ts\n", [File]),
throw({dialyzer_error, Msg})
end.
Apparently, Elixir.AAA.beam
does not exist (enoent
). The full stack trace at the throw-site is possibly more useful:
[
{:dialyzer_plt, :compute_md5_from_file, 1, [file: 'dialyzer_plt.erl', line: 543]},
{:dialyzer_plt, :compute_new_md5_1, 3, [file: 'dialyzer_plt.erl', line: 509]},
{:dialyzer_plt, :check_plt1, 3, [file: 'dialyzer_plt.erl', line: 479]},
{:dialyzer_plt, :"-subproc/1-fun-0-", 1, [file: 'dialyzer_plt.erl', line: 603]}
]
Thanks for investigating! I think we need to handle any {:dialyzer_error, binary()}
by printing the binary as an error and then halt the VM with a non-zero.
Thanks for investigating! I think we need to handle any {:dialyzer_error, binary()} by printing the binary as an error and then halt the VM with a non-zero.
Yes, that would make sense. I still wonder what triggered that exception in the first place. I tried to "fuzz" this behaviour by corrupting and removing a .beam
file, but was not able to trigger it.
I just came across this error too. I removed the /priv/plts/
and the error is gone. Leaving it here for people who might be looking for a solution.
** (CaseClauseError) no case clause matching:
{{:nocatch,
{:dialyzer_error,
[
70,
105,
108,
101,
32,
110,
111,
116,
32,
102,
111,
117,
110,
100,
58,
32,
'/opt/homebrew/Cellar/erlang/24.0.4_1/lib/erlang/lib/dialyzer-4.4.1/ebin/erl_bif_types.beam',
10
]}},
[
{:dialyzer_plt, :compute_md5_from_file, 1, [file: 'dialyzer_plt.erl', line: 543]},
{:dialyzer_plt, :compute_new_md5_1, 3, [file: 'dialyzer_plt.erl', line: 509]},
{:dialyzer_plt, :check_version, 1, [file: 'dialyzer_plt.erl', line: 328]},
{:dialyzer_plt, :check_plt1, 3, [file: 'dialyzer_plt.erl', line: 477]},
{:dialyzer_plt, :"-subproc/1-fun-0-", 1, [file: 'dialyzer_plt.erl', line: 603]}
]}
Don't know if this is the same issue but I get this:
{{:nocatch,
{:dialyzer_error,
[
78,
111,
116,
32,
97,
32,
114,
101,
103,
117,
108,
97,
114,
32,
102,
105,
108,
101,
58,
32,
'/nix/store/0lci3ngi5cqpmcb6y0ds5ri1vf6y8jyi-erlang-22.3.4.9/lib/erlang/lib/hipe-3.19.3/ebin/erl_bif_types.beam',
10
]}},
[
{:dialyzer_plt, :compute_md5_from_file, 1, [file: 'dialyzer_plt.erl', line: 543]},
{:dialyzer_plt, :compute_new_md5_1, 3, [file: 'dialyzer_plt.erl', line: 509]},
{:dialyzer_plt, :check_version, 1, [file: 'dialyzer_plt.erl', line: 328]},
{:dialyzer_plt, :check_plt1, 3, [file: 'dialyzer_plt.erl', line: 477]},
{:dialyzer_plt, :"-subproc/1-fun-0-", 1, [file: 'dialyzer_plt.erl', line: 603]}
]}
dialyzer_cl.erl:250: :dialyzer_cl.check_plt/3
dialyzer_cl.erl:183: :dialyzer_cl.plt_common/3
dialyzer.erl:160: :dialyzer.run/1
lib/dialyxir/plt.ex:219: Dialyxir.Plt.plt_run/1
lib/dialyxir/plt.ex:199: Dialyxir.Plt.plt_remove/2
lib/dialyxir/plt.ex:145: Dialyxir.Plt.check_beams/3
lib/dialyxir/plt.ex:44: Dialyxir.Plt.check_plt/4
(elixir 1.10.4) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
lib/mix/tasks/dialyzer.ex:250: Mix.Tasks.Dialyzer.check_plt/1
lib/mix/tasks/dialyzer.ex:170: Mix.Tasks.Dialyzer.run/1
(mix 1.10.4) lib/mix/task.ex:330: Mix.Task.run_task/3
(mix 1.10.4) lib/mix/cli.ex:82: Mix.CLI.run_task/2
(elixir 1.10.4) lib/code.ex:926: Code.require_file/2
Deleting all plts
folders (as @felipero) suggested didn't fix it for me. I've also tried deleting the _build
and deps
folders but even that doesn't help.
EDIT:
Oh, the fix from #335 (delete old plt files) worked for me.