Dialyzer warning has me baffled.

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Dialyzer warning has me baffled.

bengt e
Greetings,

This is on Erlang 20.3. I am at work, so if anybody could test on 21 that would be nice.

The source code below (the smallest I could make the original and still get the warning) gives me the Dialyzer warning (line 19 is first/2):
src/test_dialyzer.erl
  19
: The pattern <_, {'error', _Reason}> can never match the type <boolean() | {'error',_},[atom() | [any()] | char()]>

If I remove the first argument to key/2, Dialyzer is silent.
Is there anybody that would like to explain why I get the warning?
Is it some kind of interference between type specs? Ie, is_dets_file/1 hides {error, Reason} from oldest/1 ?


Best Wishes,
bengt


-module( test_dialyzer ).

%% API exports
-export( [key/1] ).

%%====================================================================
%% API functions
%%====================================================================

-spec( key(Name::file:filename()) -> ok ).
key( Name ) ->
O = oldest( file:list_dir(Name) ),
key( dets:is_dets_file(O), O ).

%%====================================================================
%% Internal functions
%%====================================================================

key( _, {error, _Reason} ) -> ok;
key( _, _ ) -> ok.

oldest( {ok, [H | _]} ) -> H;
oldest( {error, Reason} ) -> {error, Reason}.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Dialyzer warning has me baffled.

Brujo Benavides-3
Hi bengt,

This would be my guess:

The spec for sets:is_dets_file/1 says…
-spec is_dets_file(Filename) -> boolean() | {'error', Reason} when
      Filename :: file:name(),
      Reason :: term().

That means that, for it to work, its parameter must be of type file:name().

Therefore, in your code, dialyzer infers that your variable O is, in fact, a file:name() which of course doesn’t match with {error, Reason}.

When you remove the first argument for key/2, you’re basically removing that restriction… dialyzer can no longer infer anything about the type of O and therefore is silent.

Hope this helps.

On 17 Aug 2018, at 12:56, bengt e <[hidden email]> wrote:

Greetings,

This is on Erlang 20.3. I am at work, so if anybody could test on 21 that would be nice.

The source code below (the smallest I could make the original and still get the warning) gives me the Dialyzer warning (line 19 is first/2):
src/test_dialyzer.erl
  19
: The pattern <_, {'error', _Reason}> can never match the type <boolean() | {'error',_},[atom() | [any()] | char()]>

If I remove the first argument to key/2, Dialyzer is silent.
Is there anybody that would like to explain why I get the warning?
Is it some kind of interference between type specs? Ie, is_dets_file/1 hides {error, Reason} from oldest/1 ?


Best Wishes,
bengt


-module( test_dialyzer ).

%% API exports
-export( [key/1] ).

%%====================================================================
%% API functions
%%====================================================================

-spec( key(Name::file:filename()) -> ok ).
key( Name ) ->
O = oldest( file:list_dir(Name) ),
key( dets:is_dets_file(O), O ).

%%====================================================================
%% Internal functions
%%====================================================================

key( _, {error, _Reason} ) -> ok;
key( _, _ ) -> ok.

oldest( {ok, [H | _]} ) -> H;
oldest( {error, Reason} ) -> {error, Reason}.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Dialyzer warning has me baffled.

bengt e
Thank you very much. That makes sense. I can fix this.

My mistake was to think that Dialyzer knew the return value of oldest/1, since it is there, in the file. Whereas, to me, the spec for is_dets_file/1 is 'just a spec'. dets:is_dest_file( {not, "afile", 1} ) will return {error, Reason} and not crash.

On Fri, Aug 17, 2018 at 6:05 PM, Brujo Benavides <[hidden email]> wrote:
Hi bengt,

This would be my guess:

The spec for sets:is_dets_file/1 says…
-spec is_dets_file(Filename) -> boolean() | {'error', Reason} when
      Filename :: file:name(),
      Reason :: term().

That means that, for it to work, its parameter must be of type file:name().

Therefore, in your code, dialyzer infers that your variable O is, in fact, a file:name() which of course doesn’t match with {error, Reason}.

When you remove the first argument for key/2, you’re basically removing that restriction… dialyzer can no longer infer anything about the type of O and therefore is silent.

Hope this helps.

On 17 Aug 2018, at 12:56, bengt e <[hidden email]> wrote:

Greetings,

This is on Erlang 20.3. I am at work, so if anybody could test on 21 that would be nice.

The source code below (the smallest I could make the original and still get the warning) gives me the Dialyzer warning (line 19 is first/2):
src/test_dialyzer.erl
  19
: The pattern <_, {'error', _Reason}> can never match the type <boolean() | {'error',_},[atom() | [any()] | char()]>

If I remove the first argument to key/2, Dialyzer is silent.
Is there anybody that would like to explain why I get the warning?
Is it some kind of interference between type specs? Ie, is_dets_file/1 hides {error, Reason} from oldest/1 ?


Best Wishes,
bengt


-module( test_dialyzer ).

%% API exports
-export( [key/1] ).

%%====================================================================
%% API functions
%%====================================================================

-spec( key(Name::file:filename()) -> ok ).
key( Name ) ->
O = oldest( file:list_dir(Name) ),
key( dets:is_dets_file(O), O ).

%%====================================================================
%% Internal functions
%%====================================================================

key( _, {error, _Reason} ) -> ok;
key( _, _ ) -> ok.

oldest( {ok, [H | _]} ) -> H;
oldest( {error, Reason} ) -> {error, Reason}.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions