dialyzer(3erl)

πŸ“¦
version 25.3.2.8 Β· 4 versions
, in ubuntu noble

πŸ’… dialyzer β€” the Erlang Module Definition, bestie

okay so you're looking at dialyzer(3erl) and honestly? she's that girl. let me tell you everything.

✨ NAME ✨

dialyzer β€” Dialyzer, a DIscrepancy AnaLYZer for Erlang programs. yes the capitalization is doing a whole thing. it's an acronym. it ate.


πŸ¦‹ DESCRIPTION πŸ¦‹

So Dialyzer is a static analysis tool, which is the fancy way of saying she reads your code without running it and points at stuff that's sus. Specifically she identifies software discrepancies, and the big three are:

  • definite type errors β€” like actual, no-cap type mismatches πŸ”₯
  • code that has become dead or unreachable because of programming error β€” your program wrote a whole paragraph that will literally never be read πŸ’€
  • unnecessary tests β€” checks that are giving "extra for no reason" πŸ™ˆ

and she does this for single Erlang modules or entire (sets of) applications. small vibe, big vibe, she's down for both 🫢


Okay so where does she even start? Dialyzer gets her analysis from either:

  • debug-compiled BEAM bytecode 🧚
  • or Erlang source code 🌸

and when she finds a discrepancy, she reports the file and line number of it plus an indication of what the discrepancy is about β€” so you're never left guessing which line ghosted you.

And here's the iconic part, the main character energy: Dialyzer bases her whole analysis on the concept of success typings, and what that buys you is sound warnings β€” meaning no false positives. not one. she doesn't do false accusations, she doesn't do drama she can't back up. periodt. πŸ‘‘


ngl, "no false positives" is the entire personality and I respect it so much.

🌈 the quick rundown of what just happened

  • dialyzer = a DIscrepancy AnaLYZer for Erlang programs
  • she's a static analysis tool πŸŽ€
  • she finds definite type errors, dead or unreachable code caused by programming error, and unnecessary tests
  • she works on single Erlang modules and on entire (sets of) applications
  • her input is debug-compiled BEAM bytecode or Erlang source code
  • she tells you the file and line number of a discrepancy plus what it's about
  • she's built on success typings, which means her warnings are sound with no false positives ⭐

that's the intro, bestie β€” more sections are literally on the way πŸ’–

πŸ’» USING DIALYZER FROM THE COMMAND LINE πŸ’»

okay so bestie, Dialyzer has a whole command-line era and it's lowkey giving automation main character energy. This section is the quick rundown of the options, and you can literally summon this same info by typing this in a shell:

dialyzer --help

if you want the full lore on how Dialyzer operates, go peek at section Using Dialyzer from the GUI in the User's Guide. 🫢

Exit status of the command-line version β€” memorize these, they're the vibe check of your run:

  • 0: β€” no problems were found during the analysis and no warnings were emitted. clean girl analysis ✨
  • 1: β€” problems were found during the analysis. 😭
  • 2: β€” no problems were found during the analysis, but warnings were emitted. like, technically fine but messy πŸ’…

Usage:

dialyzer [--add_to_plt] [--apps applications] [--build_plt]
         [--check_plt] [-Ddefine]* [-Dname]* [--dump_callgraph file]
         [--error_location flag] [files_or_dirs] [--fullpath]
         [--get_warnings] [--gui] [--help] [-I include_dir]*
         [--no_check_plt] [--no_indentation] [-o outfile]
         [--output_plt file] [-pa dir]* [--plt plt] [--plt_info]
         [--plts plt*] [--quiet] [-r dirs] [--raw] [--remove_from_plt]
         [--shell] [--src] [--statistics] [--verbose] [--version]
         [-Wwarn]*
Note: the * means you can spam that option multiple times, no cap.

✨ Options of the command-line version ✨

  • --add_to_plt β€” extends the PLT so it also includes the files you specified with -c and -r. bestie, use --plt to pick which PLT you're starting from and --output_plt to say where the PLT goes after. heads up tho: the analysis can possibly pull in files from the PLT if they depend on the new files. this one only works for BEAM files, iykyk.
  • --apps applications β€” this is the one you reach for when building or modifying a PLT, like:
dialyzer --build_plt --apps erts kernel stdlib mnesia ...

so you can conveniently refer to library applications that correspond to the Erlang/OTP installation. but it's a general-purpose icon β€” you can also use it during analysis to refer to Erlang/OTP applications. file or directory names can come along too, like:

dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam
  • --build_plt β€” the analysis starts from an empty PLT and creates a fresh new one out of the files you gave with -c and -r. only works for BEAM files 🫢. wanna override the default PLT location? use --plt or --output_plt.
  • --check_plt β€” checks the PLT for consistency and rebuilds it if it's not up-to-date. the lil self-care checkup πŸŽ€
  • -Dname (or -Dname=value) β€” when you're analyzing from source, this passes the define to Dialyzer. (**)
  • --dump_callgraph file β€” dumps the call graph into the file you name, and the format is decided by the filename extension. supported extensions: raw, dot, and ps. if you use literally anything else as the filename extension, the default format .raw gets used. periodt.
  • --error_location column | line β€” use a pair {Line, Column} or a plain integer Line to pinpoint where warnings are. the default is the pair {Line, Column}. when it's formatted, the line and column are separated by a colon.
  • files_or_dirs (for backward compatibility also as -c files_or_dirs) β€” use Dialyzer from the command line to detect defects in the files or directories you specify, which contain .erl or .beam files, depending on the type of analysis you're doing.
  • --fullpath β€” displays the full path names of the files that get warnings emitted for them. no more mystery shortnames πŸ’…
  • --get_warnings β€” makes Dialyzer emit warnings even while it's manipulating the PLT. warnings are only emitted for files that are actually analyzed, so don't get it twisted.
  • --gui β€” uses the GUI. main character (derogatory, affectionate).
  • --help (or -h) β€” prints this message and exits. iconic, brief, no notes.
  • -I include_dir β€” when analyzing from source, passes the include_dir to Dialyzer. (**)
  • --input_list_file file β€” analyzes the file names listed in the specified file, one file name per line. cute lil reading list πŸ“
  • --no_check_plt β€” skips the PLT check when running Dialyzer. super useful when you're working with installed PLTs that never change β€” leave them alone, they're thriving.
  • --no_indentation β€” does not insert line breaks in types, contracts, and Erlang Code when formatting warnings. one long line, chaotic but valid.
  • -o outfile (or --output outfile) β€” when using Dialyzer from the command line, sends the analysis results to the specified outfile instead of to stdout.
  • --output_plt file β€” stores the PLT at the specified file after building it. put it somewhere nice πŸŽ€
  • -pa dir β€” includes dir in the path for Erlang. this one's a lifesaver when you're analyzing files that have -include_lib() directives.
  • --plt plt β€” uses the specified PLT as the initial PLT. if the PLT was built during setup, the files get checked for consistency.
  • --plt_info β€” makes Dialyzer print info about the PLT and then dip. you can specify the PLT with --plt(s).
  • --plts plt* β€” merges the specified PLTs to create the initial PLT. requirement tho: the PLTs must be disjoint, meaning no module can show up in more than one PLT β€” no messy overlap, bestie. the PLTs get created the usual way:
dialyzer --build_plt --output_plt plt_1 files_to_include
...
dialyzer --build_plt --output_plt plt_n files_to_include

and then you can use them in either of these ways:

dialyzer files_to_analyze --plts plt_1 ... plt_n

or

dialyzer --plts plt_1 ... plt_n -- files_to_analyze

notice the -- delimiter in the second case. don't forget it, it's doing heavy lifting πŸ™ˆ

  • --quiet (or -q) β€” makes Dialyzer a bit more quiet. shhh.
  • -r dirs β€” same as files_or_dirs, except the specified directories get searched recursively for subdirectories containing .erl or .beam files, depending on the type of analysis. she digs deep πŸ’…
  • --raw β€” when using Dialyzer from the command line, outputs the raw analysis results (Erlang terms) instead of the formatted result. the raw format is way easier to post-process (think filtering warnings, or outputting HTML pages). queen of pipelines πŸ‘‘
  • --remove_from_plt β€” the information from the files specified with -c and -r gets removed from the PLT. > watch out: this can cause a reanalysis of the remaining dependent files, so it's not a free little delete.
  • --shell β€” does not disable the Erlang shell while running the GUI.
  • --src β€” overrides the default (which is to analyze BEAM files) and analyzes starting from Erlang source code instead. reading the original text, very literary of you 🌸
  • --statistics β€” prints info about the progress of execution: analysis phases, time spent in each, and the size of the relative input. data girlies rise πŸ”₯
  • --verbose β€” makes Dialyzer a bit more verbose. it will NOT stop yapping.
  • --version (or -v) β€” prints the Dialyzer version and some more information, then exits.
  • -Wwarn β€” a whole family of options that selectively turn warnings on/off. (for help on the names of warnings, use dialyzer -Whelp.) heads up: these options can also be specified in the file with a -dialyzer() attribute β€” see section Requesting or Suppressing Warnings in Source Files for the details.
Note: ** β€” the options -D and -I work both from the command line and in the Dialyzer GUI; the syntax of defines and includes is exactly the same as the one used by erlc(1).

🌈 Warning options 🌈

  • -Werror_handling (***) β€” includes warnings for functions that only return by an exception.
  • -Wextra_return (***) β€” warns about functions whose specification includes types that the function cannot return.
  • -Wmissing_return (***) β€” warns about functions that return values that aren't part of the specification.
  • -Wno_behaviours β€” suppresses warnings about behavior callbacks that drift from the published recommended interfaces. they're doing their best okay 😭
  • -Wno_contracts β€” suppresses warnings about invalid contracts.
  • -Wno_fail_call β€” suppresses warnings for failing calls.
  • -Wno_fun_app β€” suppresses warnings for fun applications that will fail.
  • -Wno_improper_lists β€” suppresses warnings for construction of improper lists.
  • -Wno_match β€” suppresses warnings for patterns that are unused or cannot match. ghosted patterns πŸ’€
  • -Wno_missing_calls β€” suppresses warnings about calls to missing functions.
  • -Wno_opaque β€” suppresses warnings for violations of opacity of data types. respect the privacy bestie πŸ™ˆ
  • -Wno_return β€” suppresses warnings for functions that will never return a value.
  • -Wno_undefined_callbacks β€” suppresses warnings about behaviors that have no -callback attributes for their callbacks.
  • -Wno_unused β€” suppresses warnings for unused functions.
  • -Wunderspecs (***) β€” warns about underspecified functions (the specification is strictly more allowing than the success typing).
  • -Wunknown (***) β€” lets warnings about unknown functions and types affect the exit status of the command-line version. the default is to ignore warnings about unknown functions and types when setting the exit status. when you're using Dialyzer from Erlang, warnings about unknown functions and types are returned; the default is not to return these warnings.
  • -Wunmatched_returns (***) β€” includes warnings for function calls that ignore a structured return value or don't match against one of many possible return values. however! no warnings are included if the possible return values are a union of atoms or a union of numbers.

The following options are also available, but their use is not recommended (they're mostly for Dialyzer developers and internal debugging, so like... you're not supposed to be here unless you are):

  • -Woverspecs (***) β€” warns about overspecified functions (the specification is strictly less allowing than the success typing).
  • -Wspecdiffs (***) β€” warns when the specification is different than the success typing.
Note: *** denotes options that turn warnings on rather than turning them off. the triple stars are the "warnings go brrr" club ⭐

The following option isn't strictly needed because it just specifies the default. it's primarily intended to be used with the -dialyzer attribute β€” for an example, see section Requesting or Suppressing Warnings in Source Files.

  • -Wno_underspecs β€” suppresses warnings about underspecified functions (the specification is strictly more allowing than the success typing).
  • -Wno_extra_return β€” suppresses warnings about functions whose specification includes types that the function cannot return.
  • -Wno_missing_return β€” suppresses warnings about functions that return values that aren't part of the specification.

πŸ¦‹ USING DIALYZER FROM ERLANG πŸ¦‹

Dialyzer can be used directly from Erlang β€” no command line needed, we're going straight to the source πŸ’œ. Both the GUI and the command-line versions are also available, and the options are similar to the ones you'd give from the command line, so hop up to section Using Dialyzer from the Command Line. iykyk ✨

πŸŽ€ DEFAULT DIALYZER OPTIONS πŸŽ€

okay so the host operating system environment variable ERL_COMPILER_OPTIONS is literally how you give Dialyzer default options. its value has to be a valid Erlang term. if the value is a list, it is used as is; if it is not a list, it is put into a list.

that list is appended to any options given to run/1 or on the command line. you can retrieve the list with compile:env_compiler_options/0.

currently the only option used is the error_location option. that's it, that's the tea β˜•βœ¨


✨ REQUESTING OR SUPPRESSING WARNINGS IN SOURCE FILES ✨

the attribute -dialyzer() can be used for turning off warnings in a module by specifying functions or warning options. for example, to turn off all warnings for the function f/0, include the following line:

-dialyzer({nowarn_function, f/0}).

to turn off warnings for improper lists, add the following line to the source file:

-dialyzer(no_improper_lists).

attribute -dialyzer() is allowed after function declarations. lists of warning options or functions are allowed:

-dialyzer([{nowarn_function, [f/0]}, no_improper_lists]).

warning options can be restricted to functions:

-dialyzer({no_improper_lists, g/0}).
-dialyzer({[no_return, no_match], [g/0, h/0]}).

the warning option for underspecified functions, -Wunderspecs, can result in useful warnings, but ngl, often functions with specifications that are strictly more allowing than the success typing cannot easily be modified to be less allowing. to turn off the warning for underspecified function f/0, include the following line:

-dialyzer({no_underspecs, f/0}).

for help on the warning options, use dialyzer -Whelp. the options are also enumerated, see type warn_option().

Note: warning option -Wrace_conditions has no effect when set in source files. πŸ’€

attribute -dialyzer() can also be used for turning on warnings. for example, if a module has been fixed regarding unmatched returns, adding the following line can help in assuring that no new unmatched return warnings are introduced:

-dialyzer(unmatched_returns).

🌈 DATA TYPES 🌈

here's the type tea, bestie β˜•πŸ’–

dial_option() =
    {files, [FileName :: file:filename()]} |
    {files_rec, [DirName :: file:filename()]} |
    {defines, [{Macro :: atom(), Value :: term()}]} |
    {from, src_code | byte_code} |
    {init_plt, FileName :: file:filename()} |
    {plts, [FileName :: file:filename()]} |
    {include_dirs, [DirName :: file:filename()]} |
    {output_file, FileName :: file:filename()} |
    {output_plt, FileName :: file:filename()} |
    {check_plt, boolean()} |
    {analysis_type,
     succ_typings | plt_add | plt_build | plt_check | plt_remove} |
    {warnings, [warn_option()]} |
    {get_warnings, boolean()} |
    {error_location, error_location()}

tiny but important: the from option defaults to byte_code, and init_plt and plts change that default.

dial_warn_tag() =
    warn_behaviour | warn_bin_construction | warn_callgraph |
    warn_contract_not_equal | warn_contract_range |
    warn_contract_subtype | warn_contract_supertype |
    warn_contract_syntax | warn_contract_types |
    warn_failing_call | warn_fun_app | warn_map_construction |
    warn_matching | warn_non_proper_list | warn_not_called |
    warn_opaque | warn_return_no_exit | warn_return_only_exit |
    warn_undefined_callbacks | warn_unknown | warn_umatched_return
dial_warning() =
    {Tag :: dial_warn_tag(),
     Id :: file_location(),
     Msg :: {atom(), [term()]}}
error_location() = column | line

if the value of this option is line, an integer Line is used as Location in messages. if the value is column, a pair {Line, Column} is used as Location. the default is column.

file_location() =
    {File :: file:filename(), Location :: erl_anno:location()}
warn_option() =
    error_handling | no_behaviours | no_contracts | no_fail_call |
    no_fun_app | no_improper_lists | no_match | no_missing_calls |
    no_opaque | no_return | no_undefined_callbacks |
    no_underspecs | no_unused | underspecs | unknown |
    unmatched_returns | overspecs | specdiffs | extra_return |
    no_extra_return | missing_return | no_missing_return

see section Warning options for a description of the warning options. iykyk πŸ’…


πŸ‘‘ EXPORTS πŸ‘‘

πŸ’… format_warning(Warnings) -> string()

Types:

Warnings = dial_warning()

get a string from warnings as returned by run/1.

πŸ’… format_warning(Warnings, Options) -> string()

Types:

Warnings = dial_warning()
Options = filename_opt() | [format_option()]
format_option() =
    {indent_opt, boolean()} |
    {filename_opt, filename_opt()} |
    {error_location, error_location()}
filename_opt() = basename | fullpath

get a string from warnings as returned by run/1.

if indent_opt is set to true (default), line breaks are inserted in types, contracts, and Erlang code to improve readability.

if error_location is set to column (default), locations are formatted as Line:Column if the column number is available, otherwise locations are formatted as Line even if the column number is available.

🧚 gui() -> ok

🧚 gui(Options) -> ok

Types:

Options = [dial_option()]

Dialyzer GUI version. iconic ✨

πŸ¦‹ plt_info(Plt) -> {ok, Result} | {error, Reason}

Types:

Plt = file:filename()
Result = [{files, [file:filename()]}]
Reason = not_valid | no_such_file | read_error

returns information about the specified PLT. slay 🫢

⭐ run(Options) -> Warnings

Types:

Options = [dial_option()]
Warnings = [dial_warning()]

Dialyzer command-line version.


xoxo bestie πŸ’– this masterpiece is brought to you by Ericsson AB, version dialyzer 5.0.5, for manual dialyzer(3erl) πŸŽ€βœ¨
πŸ“¦ where this page comes from