[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