Age | Commit message (Collapse) | Author |
|
By default Dialyzer tries to improve the readability of warnings.
Newlines are inserted before and inside types, signatures, and Erlang
code. Sometimes the newlines look misplaced. The raw format
(option --raw) is not affected.
Use the new --no_indentation option get the old behavior (no inserted
line breaks).
A note on the implementation. The types &c present in the warning
tuples are parsed, and then formatted using erl_pp, the Erlang Pretty
Printer. The alternative, to create message tuples with formatted
types, turned out to more complicated, and has no real benefits.
Also notice that the fixes for binaries (commit 9db8a098) and union
elements (commit a1e51d12) are required. As a consequence, messages
created before these commits using the --raw option cannot always be
indented.
|
|
See also https://bugs.erlang.org/browse/ERL-845.
Fix a bug that caused Dialyzer to crash when analyzing a contract with
a module name differing from the analyzed module's name. The bug was
introduced in Erlang/OTP 18.
|
|
The -Woverspecs (-Wspecdiffs) option generates warnings in a few more
cases. The refinement is analogous to the test that -Wunderspecs
already does: it checks if the contract has nothing in common with
some element (see erl_types:t_elements/1) of the success typing.
|
|
|
|
The implementation of OTP-14218 (commit 6d3b38a) has a weakness: only
a very limited part of the type form is checked. This is now fixed:
types not used by specs are checked equally well as types used by
specs.
The new function erl_types:t_from_form_check_remote() checks usage of
remote types. It does not expand used local types, and has (almost) no
limits on depth and size.
|
|
Avoid some ETS-lookups. Marginal speed-ups.
|
|
|
|
The -T option has not been working for a long time.
|
|
The table used during translation of forms to types used to be a
dictionary of the type info (-type(), -opaque(), and -record()) for
all modules. Now it is reduced to the modules that are needed to
handle references to types in other modules.
The PLT:s type info is still kept on the heap.
|
|
* maint:
dialyzer: Compact 'file' annotations in Core code
dialyzer: Try to reduce memory usage
dialyzer: Use less memory when translating contracts
dialyzer: Use maps instaed of dict
dialyzer: Use maps instead of dict for module contracts map
dialyzer: Compress a few more ETS tables
dialyzer: Optimize memory consumption
dialyzer: Reduce memory consumption during 'remote' phase
dialyzer: Update code for finding parallelism
compiler: Do not spawn process when dialyzing
dialyzer: Reduce ETS usage during the typesig phase
dialyzer: Optimize graph condensation
dialyzer: Do not send full PLTs as messages
|
|
The translation from forms to types is done in a separate process
in an attempt to reduce peak memory usage.
Expect further optimizations as it is probably not feasible
in the long run to keep all type information on the heap.
|
|
|
|
|
|
Some SCC info is no longer cached. It reduces the peak memory
consumption of workers during the typesig phase, and seems to cost
very little time.
|
|
The cache used for speeding up the translation from forms to types is
no longer global, but reset per module. The peak memory consumption
is reduced, and the added time seems to be small.
|
|
The mini PLT is extended to hold all data of the full PLT, and the
full PLT is restored when needed (for storing the PLT on file).
|
|
|
|
Messages like "Invalid type specification for function
para3:exp_adt/0. The success typing is () -> 3" now look like
"The specification for para3:exp_adt/0 has an opaque subtype
para3_adt:exp1(para3_adt:exp2()) which is violated by the success
typing () -> 3".
The old message did not give any clue as to what invalidated the
contract, namely the opaque subtype.
|
|
|
|
|
|
Dialyzer failed to remove all loops among constraints.
|
|
and do the following changes:
in erl_types: export the type and an appropriate constructor for it
in dialyzer_contracts: perform all necessary code modifications to
fix all dialyzer warnings
Although no warnings are reported by dialyzer, it's quite possible that
these are not the only places where the opacity of the var_table() data
structure is violated. But I decided to leave these places for a better
version of dialyzer to discover...
|
|
Optimization: A few dictionaries are maps instead of dicts.
|
|
This is analogous to the case of nil. Since #{} is a base-case of almost
all map types, contract and success typing sharing #{} does not mean
much, and is often sign of a violation.
|
|
|
|
|
|
Add more information about the caller of t_from_form(). Instead of
just the module, also provide name of the type, spec, or record where
the type form resides.
|
|
|
|
|
|
The check that a modified type of a field is a subtype of the declared
type has been moved outside of the expansion of forms to avoid loops.
|
|
In particular fix handling of records.
|
|
The -dialyzer() attribute can be used for suppressing warnings in a
module by specifying functions or warning options. It can also be used
for requesting warnings in a module.
|
|
* maint:
dialyzer: fix a -Wunderspecs bug
|
|
Sometimes bogus warnings were generated for parametrized types.
Thanks to Krzesimir Sarnecki for pointing the bug out.
Also corrected warnings where the structure of opaque types were
exposed (thanks to Kostis for pointing the bug out).
|
|
* maint:
hipe: fix a bug concerning typed record fields
|
|
When checking typed record fields Dialyzer failed to handle
types containing remote types.
Thanks to Erik Søe Sørensen for reporting this bug.
|
|
|
|
Guard constraints used to be limited to a certain depth, which handled
mutually depending constraints safely, but also sometimes introduced
unnecessary generalizations.
This patch puts no explicit limit upon guard constraints (other than
those that already exist in erl_types), but breaks cycles by replacing
variables with the any() type.
In some cases the old method resulted in more warnings, but since the
limit was quite arbitrary and mutually depending guard constraints are
(very) rare, the new method should been seen as an improvement since
it handles cases that used to make Dialyzer loop or miss warnings.
|
|
The types array(), dict(), digraph(), gb_set(), gb_tree(), queue(),
set(), and tid() have been deprecated. They will be removed in OTP 18.0.
Instead the types array:array(), dict:dict(), digraph:graph(),
gb_set:set(), gb_tree:tree(), queue:queue(), sets:set(), and ets:tid()
can be used. (Note: it has always been necessary to use ets:tid().)
It is allowed in OTP 17.0 to locally re-define the types array(), dict(),
and so on.
New types array:array/1, dict:dict/2, gb_sets:set/1, gb_trees:tree/2,
queue:queue/1, and sets:set/1 have been added.
|
|
Handle immediate opaque types as aliases:
A declaration of dict/0
-opaque dict() :: dict(_, _).
-opaque dict(Key, Value) :: ...
is handled as an alias, that is, when using dict() it is immediately
replaced by dict(_, _).
This is a means to avoid having to handle equivalent opaque types
later. To be changed if it doesn't work well.
|
|
It is now OK to inspect and modify the internals of opaque types within
the scope of the module.
The contracts are used for decorating types with opaqueness when it is
harmless to do so. The opaqueness is propagated by the typesig module
and also by the dataflow module.
A lot of details have been fixed or updated. In particular the modules
erl_types and erl_bif_types have been modified extensively.
The version in vsn.mk has been updated to 2.7. The reason is a
modification of #opaque{} in erl_types.
Dialyzer seems to be about five percent slower than it used to be.
|
|
|
|
The function name can give information that the line number doesn't,
for example when using a parse transform that creates new functions.
|
|
This patch enables Dialyzer to detect cases where a function has a specification
for a return type containing some list with elements different than the ones
Dialyzer's own algorithm can infer e.g. a function specified to return [atom()]
when actually [[atom()]] is returned.
Previously Dialyzer remained silent, under normal operation, seeing that these
two types have the empty list as a common element, so they were not 'completely
irrelevant'.
|
|
|
|
Variables in contracts can either be true type variables or simply names for
types thet are defined in the 'when' clauses. Consider the following example:
-spec foo(X, Options) -> {ok, X} | error when Options :: [{atom(), boolean()}].
Here X is a true variable whereas Options is a name for a type that is defined
in the when clause.
'when' clauses may further use names on the right side. These were not treated
properly by Dialyzer and could be generalized to the term() type. This patch
fixes this issue.
A further issue is the treatment of true type variables, but this is left for
another patch.
|
|
|
|
|
|
|
|
|