[erlang-questions] Dialyzer and record MatchSpec warnings

Tobias Lindahl tobias.lindahl@REDACTED
Tue Feb 3 09:36:00 CET 2009


Maxim Treskin wrote:
> Hello
> 
> I found incomprehensible thing in dialyzer's output for MatchSpec using
> records.
> 
> This is my module:
> =======================================
> -module(loc).
> -export([get_ctrl_good/1, get_ctrl_bad/1]).
> 
> -record(controller, {
>           id :: integer(),
>           address :: any(),
>           type :: any(),
>           name :: string(),
>           profile :: integer()
>          }).
> 
> get_ctrl_good(CtrlId) ->
>     CtrlMS = [{#controller{id = CtrlId, _='_'}, [], ['$_']}],
>     case mnesia:dirty_select(controller, CtrlMS) of
>         [Controller] -> [Controller];
>         _ -> not_found
>     end.
> 
> get_ctrl_bad(CtrlId) ->
>     CtrlMS = [{#controller{id = CtrlId}, [], ['$_']}],
>     case mnesia:dirty_select(controller, CtrlMS) of
>         [Controller] -> [Controller];
>         _ -> not_found
>     end.
> =======================================
> 
> So, when I make dialyzer --src -c loc.erl, I see following output:
> 
>   Checking whether the PLT /home/zert/.dialyzer_plt is up-to-date... yes
>   Proceeding with analysis...
> loc.erl:13: Function get_ctrl_good/1 has no local return
> loc.erl:14: Record construction
> #controller{id::any(),address::'_',type::'_',name::'_',profile::'_'}
> violates the declared type for #controller{}
>  done in 0m0.59s
> done (warnings were emitted)
> 
> get_ctrl_bad/1 not contains _='_' in MatchSpec for dirty_select query and
> does not work due to unassignet fileds of record became to undefined value.
> get_ctrl_good/1 works fine, but dialyzer not think so.
> BTW, I know about ets:ms2fun, it gave me same results as in get_ctrl_good/1

Yes, you found a bit of a problem there. You are indeed constructing a 
record that do not conform to the specification you have given. The atom 
'_' is not part of the declared type, so Dialyzer tells you that you 
have broken the contract, which you arguably have done. However, you do 
want to give that assignment for the match spec to work correctly.

The quick fix is to include '_' in the specified type for all fields you 
want to assign to '_'. A more general fix might be that Dialyzer always 
accepts '_' for construction since match specs are quite common. We'll 
have to think about that.

Thanks for the report.

Tobias


> 
> My OTP release is R12B-5.
> 
> How I can make this code right?
> 
> Thank you
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list