Dialyzer warning when returning a prolist

Paulo Zulato paulozulato@REDACTED
Tue May 18 00:28:39 CEST 2021


Hi, Fernando,

Thank you for your reply. I tried enabling other warnings as well, but the
result was the same:
rebar.config

> {erl_opts, [debug_info]}.
> {deps, []}.
> {dialyzer, [{warnings, [error_handling, underspecs, unknown,
> unmatched_returns]}]}.
>

test.erl

> -module(test).
>
> -export([test/0]).
>
> %% From <https://erlang.org/doc/man/proplists.html>
> -type property() :: atom() | tuple().
> -type proplist() :: [property()].
> -spec test() -> proplist().
> test() ->
>    [
>        {one_test, [a,b,c]},
>        {another_test, [d,e,f]}
>    ].
>

$ rebar3 dialyzer

> ===> Verifying dependencies...
> ===> Analyzing applications...
> ===> Compiling test
> ===> Dialyzer starting, this may take a while...
> ===> Updating plt...
> ===> Resolving files...
> ===> Checking 202 files in _build/default/rebar3_23.2.6_plt...
> ===> Doing success typing analysis...
> ===> Resolving files...
> ===> Analyzing 1 files with _build/default/rebar3_23.2.6_plt...
>
> src/test.erl
>   Type specification test:test() -> proplist() is a supertype of the
> success typing: test:test() -> [{'another_test',['d' | 'e' | 'f',...]} |
> {'one_test',['a' | 'b' | 'c',...]},...]
> ===> Warnings written to _build/default/23.2.6.dialyzer_warnings
> ===> Warnings occurred running dialyzer: 1
>

But:
test.erl

> -module(test).
>
> -export([test/0]).
>
> -spec test() -> proplists:proplist().
> test() ->
>    [
>        {one_test, [a,b,c]},
>        {another_test, [d,e,f]}
>    ].
>

$ rm -rf _build
$ rebar3 dialyzer

> ===> Verifying dependencies...
> ===> Analyzing applications...
> ===> Compiling test
> ===> Dialyzer starting, this may take a while...
> ===> Updating plt...
> ===> Resolving files...
> ===> Updating base plt...
> ===> Resolving files...
> ===> Checking 202 files in
> ../../home/pzulato/.cache/rebar3/rebar3_23.2.6_plt...
> ===> Copying ../../home/pzulato/.cache/rebar3/rebar3_23.2.6_plt to
> _build/default/rebar3_23.2.6_plt...
> ===> Checking 202 files in _build/default/rebar3_23.2.6_plt...
> ===> Doing success typing analysis...
> ===> Resolving files...
> ===> Analyzing 1 files with _build/default/rebar3_23.2.6_plt...
>

So I believe it's something else.


Best regards,
Paulo Zulato

--
«Quis custodiet ipsos custodes?»


On Mon, 17 May 2021 at 17:47, Fernando Benavides <elbrujohalcon@REDACTED>
wrote:

> Probably because proplists:proplist() is not in your PLT.
>
> Have you tried enabling the unknown warning for dialyzer?
>
> It will likely tell you that it doesn't know the proplists:proplist/0 type.
>
> On Mon, 17 May 2021 at 22:25 Paulo Zulato <paulozulato@REDACTED> wrote:
>
>> Hello,
>>
>> I'm trying to figure out why dialyzer is complaining about a function
>> when I don't explicitly declare its return as a proplist.
>> I have this small module which returns a proplist in the form {atom(),
>> [atom()]}:
>>
>>> -module(test).
>>>
>>> -export([test/0]).
>>> test() ->
>>>    [
>>>        {one_test, [a,b,c]},
>>>        {another_test, [d,e,f]}
>>>    ].
>>>
>>
>> For function above, I made the following spec, but dialyzer has
>> complained (as stated below) when I enabled its underspecs warnings.
>>
>>> -spec test() -> [{atom(), [atom()]}].
>>> % src/test.erl
>>> %    Type specification test:test() -> [{atom(),[atom()]}] is a
>>> supertype of the success typing: test:test() -> [{'another_test',['d' | 'e'
>>> | 'f',...]} | {'one_test',['a' | 'b' | 'c',...]},...]
>>>
>>
>> Well... both lists are non-empty lists as stated by dialyzer, so I
>> modified the spec, without success:
>>
>>> -spec test() -> [{atom(), [atom(), ...]}, ...].
>>> %src/test.erl
>>> %   Type specification test:test() -> [{atom(),[atom(),...]},...] is a
>>> supertype of the success typing: test:test() -> [{'another_test',['d' | 'e'
>>> | 'f',...]} | {'one_test',['a' | 'b' | 'c',...]},...]
>>>
>>
>> Then I tried to explicitly declare it as a proplist, and dialyzer has
>> accepted it:
>>
>>> -spec test() -> proplists:proplist().
>>> % OK, no warnings.
>>>
>>
>> As it worked, I tried to do the same as proplists module does and created
>> two types, which I used on my new spec. And, surprisingly, dialyzer has
>> complained about it!
>>
>>> % From <https://erlang.org/doc/man/proplists.html>
>>> -type property() :: atom() | tuple().
>>> -type proplist() :: [property()].
>>>
>>
>>> -spec test() -> proplist().
>>> %src/test.erl
>>>
>> %   Type specification test:test() -> proplist() is a supertype of the
>>> success typing: test:test() -> [{'another_test',['d' | 'e' | 'f',...]} |
>>> {'one_test',['a' | 'b' | 'c',...]},...]
>>>
>>
>> Therefore, I could not understand why declaring the return as
>> "proplists:proplist" is OK while declaring it as lists, nonempty lists or
>> creating the same types as proplists are not OK. Why is dialyzer
>> complaining about the other specs? Is dialyzer handling proplists in a
>> different way? Could someone help me to understand this behaviour?
>>
>>
>> Best Regards,
>> Paulo Zulato
>>
>> --
>> «Quis custodiet ipsos custodes?»
>>
> --
> Sent from Gmail Mobile by Brujo Benavides
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20210517/418ad2a7/attachment.htm>


More information about the erlang-questions mailing list