Dialyzer: Cons will produce an improper list since its 2nd argument is none()

Richard Carlsson carlsson.richard@REDACTED
Fri Feb 14 15:48:09 CET 2020


Nice answer, Brujo! I think the only confusion here is the warning about
the improper list; without that one, everything should have been clear. The
check for improper lists ought to ignore the case when the tail is none(),
since it means that the result will also be none() anyway.

        /Richard


Den fre 14 feb. 2020 kl 14:05 skrev Jesper Eskilson <
jesper.eskilson@REDACTED>:

> Ah, my question wasn't why the error occurs in the first place, but rather
> an inquiry if dialyzer oughtn't formulate the error a bit differently. :)
>
>
> On Fri, Feb 14, 2020 at 1:54 PM Fernando Benavides <
> elbrujohalcon@REDACTED> wrote:
>
>> I think what's happening in this case is this…
>> Dialyzer sees your code (using cons for the list) as…
>>
>> main() -> [ #foo{x = 0} | [#foo{x = false} | []] ].
>>
>> It then detects the third warning from your email (namely, that you're
>> using *false* for something that should be an *integer*):
>> foo.erl:9: Record construction
>>           #foo{x :: false} violates the declared type of field x ::
>>           integer()
>> Therefore, the type of that second part of the list ([#foo{x = false} |
>> []]) will be *none()*.
>> And that leads dialyzer to complain with the second warning that you see…
>> foo.erl:8: Cons will produce an improper list since its 2nd argument is
>>           none()
>> Which, in time, produces the first warning…
>> foo.erl:7: Function main/0 has no local return
>>
>> Hope this helps.
>>
>> On Fri, Feb 14, 2020 at 1:45 PM Jesper Eskilson <
>> jesper.eskilson@REDACTED> wrote:
>>
>>> Hi,
>>>
>>> When dialyzer analyzes this program:
>>>
>>>
>>> -module(foo).
>>> -export([main/0]).
>>> -record(foo, {x :: integer()}).
>>> main() ->
>>>   [ #foo{x = 0},
>>>     #foo{x = false} ].
>>>
>>>
>>> it says:
>>>
>>> foo.erl:7: Function main/0 has no local return
>>> foo.erl:8: Cons will produce an improper list since its 2nd argument is
>>>           none()
>>> foo.erl:9: Record construction
>>>           #foo{x :: false} violates the declared type of field x ::
>>>           integer()
>>>
>>>
>>> It seems like dialyzer assumes that any cons with second argument not
>>> being a list will produce an improper list, but shouldn't it treat "none()"
>>> differently?
>>>
>>> Is this a bug in dialyzer, or a feature whose usefulness I am unable to
>>> grasp?
>>>
>>> --
>>>
>>> *Jesper Eskilson*
>>> Senior Software Engineer
>>> Kred Core
>>> +46-72-855-8421
>>>
>>> Klarna Bank AB (publ)
>>> Sveavägen 46, 111 34 Stockholm
>>> Tel: +46 8 120 120 00 <+46812012000>
>>> Reg no: 556737-0431
>>> klarna.com
>>>
>>>
>>
>> --
>>
>> <https://about.me/elbrujohalcon?promo=email_sig&utm_source=product&utm_medium=email_sig&utm_campaign=gmail_api&utm_content=thumb>
>> Brujo Benavides
>> about.me/elbrujohalcon
>> <https://about.me/elbrujohalcon?promo=email_sig&utm_source=product&utm_medium=email_sig&utm_campaign=gmail_api&utm_content=thumb>
>>
>
>
> --
>
> *Jesper Eskilson*
> Senior Software Engineer
> Kred Core
> +46-72-855-8421
>
> Klarna Bank AB (publ)
> Sveavägen 46, 111 34 Stockholm
> Tel: +46 8 120 120 00 <+46812012000>
> Reg no: 556737-0431
> klarna.com
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20200214/0ebbbaa5/attachment.htm>


More information about the erlang-questions mailing list