Background
As some of you know, the newest version of Elixir (1.7.3) has a bug that prevents the usage of dialyzer . This specially affects the 1.7.3-otp-21
release.
Now, I am aware that some previous versions were free from this problem, but I don’t know which ones.
Question
What is the latest version of elixir-otp-erlang that is not affected by this bug?
1.7.2-otp-21 seemed to work fine when I last run it
2 Likes
1.7.3 isn’t the newest, I’m running:
╰─➤ elixir --version
Erlang/OTP 21 [erts-10.1.1] [source] [64-bit] [smp:6:6] [ds:6:6:10] [async-threads:1] [hipe]
Elixir 1.7.4 (compiled with Erlang/OTP 21)
And I use dialyzer excessively without issue?
1 Like
NobbZ
November 15, 2018, 10:22pm
4
try
/catch
produces byte code that makes dialyzer complain.
I’m looking at a large try
/catch
in my large codebase here and dialyzer is running cleanly (it really shouldn’t, but it is, the lackings of it being a positive typer)? Is it only certain forms of try
/catch
constructs?
NobbZ
November 15, 2018, 10:45pm
6
You even liked the post where I link to the issue on github…
opened 10:16PM - 31 Aug 18 UTC
closed 07:42PM - 14 Sep 18 UTC
Kind:Bug
Level:Intermediate
App:Elixir (compiler)
### Environment
* Elixir & Erlang/OTP versions (elixir --version):
```
Erl… ang/OTP 21 [erts-10.0.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Elixir 1.7.2 (compiled with Erlang/OTP 21)
```
* Operating system: Mac OS/X High Sierra 10.13.6
### Current behavior
Dialyzer produces warnings on generated exception-handling code in the `try` macro when a `rescue` clause matches on `ErlangError`. Minimal example:
```elixir
defmodule TryTupleSize do
def demo do
try do
:erlang.error(:badarg)
rescue
e in ErlangError ->
{:ok, e}
end
end
end
```
Dialyzer output:
```
try_tuple_size.ex:6: Guard test tuple_size(__@5::#{'__exception__':='true', '__struct__':=_, _=>_}) can never succeed
```
The decompiled-to-Erlang version of the `demo/0` function:
```erlang
demo() ->
try
error(badarg)
catch
error:__@3:___STACKTRACE__@1 when not is_map(__@3) ->
_e@1 =
'Elixir.Exception':normalize(error,
__@3,
case __@3 of
__@5
when
tuple_size(__@5)
==
2
andalso
element(1,
__@5)
==
badkey;
__@5 == undef;
__@5
==
function_clause ->
___STACKTRACE__@1;
_ ->
[]
end),
{ok,_e@1};
error:#{'__struct__' := __@4,'__exception__' := true} = __@3:___STACKTRACE__@1
when __@4 == 'Elixir.ErlangError' ->
_e@1 =
'Elixir.Exception':normalize(error,
__@3,
case __@3 of
__@5
when
tuple_size(__@5)
==
2
andalso
element(1,
__@5)
==
badkey;
__@5 == undef;
__@5
==
function_clause ->
___STACKTRACE__@1;
_ ->
[]
end),
{ok,_e@1}
end.
```
### Expected behavior
In the case where the (second) generated `catch` branch has already matched on an exception map/struct, it should not use `tuple_size/1` in that clause. Furthermore, since it has already established that the error has been normalized, it shouldn't be trying to normalize the error again. This could remove the type warning from the generated code.
So, yes, I think we can consider this confirmed.
Hmm, actually I think my big server might still be running 1.6.something, so that would explain it (similar issue to the syntax parsing bug I posted recently too, that server is not on 1.7 yet…)
NobbZ
November 15, 2018, 10:52pm
8
Well, you can ignore those warnings for now.
To be honest, I have not even discovered this bug until you put my nose into it.
I do not consider 1.7 bad just because of this small thing.
1 Like
I have tested the following builds:
1.7.2-otp-21
1.7.3-otp-21
1.7.4-otp-21
All failed to work properly.
The bug can be reproduced with the MWE:
https://github.com/Fl4m3Ph03n1x/dialyxir-problem
Does anyone know any other builds?
I’m unable to test it right now but I’m positive it works - dialyzer (at least on MacOSX 10.13) I have no idea about prometheus, make sure you remove the _build
folder and re-compile if you haven’t between tries and make sure that you’re actually running with those versions of the build (and if you installed dialyxir globally as an archive you might also need to clean it up?)
amnu3387:
I’m unable to test it right now but I’m positive it works - dialyzer (at least on MacOSX 10.13) I have no idea about prometheus, make sure you remove the _build
folder and re-compile if you haven’t between tries and make sure that you’re actually running with those versions of the build (and if you installed dialyxir globally as an archive you might also need to clean it up?)
It most definitely doesn’t work.
I have a _build
folder
Every time you run mix dialyzer
, if the runtime has changed, the entire project gets recompiled automatically
I don’t have dialyxir installed globally. That’s just pain waiting to happen
Let me know if you have the time to test it, I am curious now.