Re: Dialyzer warning when returning a prolist

Paulo Zulato <[email protected]>
Newsgroups gmane.comp.lang.erlang.general
Message-ID <CAATrJfdryFfmQeYonGwTgMgXjrT+4PbPkMdfdYSyApYfD+++xA@mail.gmail.com>
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 <[email protected]>
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 <[email protected]> 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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.