[erlang-questions] code:lib_dir and dialyzer
Kostis Sagonas
kostis@REDACTED
Wed Jan 7 15:22:23 CET 2009
Nicolas Charpentier wrote:
> Hi,
>
> Running Dialyzer (1.8.3) on my code, I got an error on a call to
> code:lib_dir/1.
>
> Here is the code:lib_dir/1 source:
> %% XXX is_list() is for backwards compatibility -- take out in future
> version
> -spec lib_dir(App :: atom()) -> string() | {'error', 'bad_name'}.
> lib_dir(App) when is_atom(App) ; is_list(App) -> call({dir,{lib_dir,App}}).
>
> And here is my test code:
> test_lib_dir() ->
> Path = code:lib_dir(kernel),
> Path = code:lib_dir("kernel").
>
> Both calls to code:lib_dir/1 are valid on a runtime system even if the
> clause with the string parameter is kept for backward compatibility
>
> Running Dialyzer on my code, I'm expecting an error like this:
> "The call code:lib_dir([101 | 107 | 108 | 110 | 114,...]) breaks the
> contract (atom()) -> string() | {'error', 'bad_name'}".
>
> But I got this one:
> "The call code:lib_dir([101 | 107 | 108 | 110 | 114,...]) will never
> return since it differs in argument position 1 from the success typing
> arguments: (atom())"
>
>
> Is it a dialyzer bug ?
In some sense yes, but I would really describe/classify this as an
inconsistency more than a bug.
The problem is that Dialyzer (still) has hard-coded information about
some library functions in hipe/cerl/erl_bif_types.erl. This information
pre-dates the language of contracts and shadows the -spec information.
For the function in question dialyzer knows that:
arg_types(code, lib_dir, 1) ->
[t_atom()];
which explains why you get the error message that you get. Now that
contracts are present in code, arguably this information is no longer
needed and can (should?) be taken out -- at least for functions of this
module.
Regardless, I would suggest that you fix your code to adhere to the
published documentation and use code:lib_dir/1 with a string() instead.
Kostis
More information about the erlang-questions
mailing list