Age | Commit message (Collapse) | Author |
|
|
|
Also modified erl_bif_types:infinity_bsl() when called with zero as
first argument. As of writing this, erlang:'bsl'/2 is modified on the
master branch to never fail if called with a huge second argument.
|
|
|
|
See also https://bugs.erlang.org/browse/ERL-551.
|
|
|
|
* maint:
stdlib: Correct signatures of functions in erl_parse
|
|
The signatures of erl_parse:anno_to_term/1 and
erl_parse:anno_from_term/1 are corrected. Using these function no
longer results in false Dialyzer warnings.
|
|
* maint:
stdlib: Allow characters in types and constant patterns
|
|
Characters ($char) can be used in constant pattern expressions. They
can also be used in types and contracts.
|
|
* maint:
dialyzer: Substitute 'opacity' for 'opaqueness'
dialyzer: Improve a warning message
dialyzer: Improve a warning message
dialyzer: Correct a warnings message
|
|
Messages regarding guards with orelse/andalso could look
like "Clause guard cannot succeed. The variable A was matched
against the type any()". Now they look like as if or/and is
used: "Guard test is_integer(A::atom()) can never succeed".
|
|
* maint:
Update preloaded
erts: Correct type declaration of match specification head
Conflicts:
erts/preloaded/ebin/erlang.beam
erts/preloaded/ebin/erts_internal.beam
|
|
Bug reported by Peti Gömöri <[email protected]>.
|
|
The previous variable names can be generated by
projects like LFE and Elixir, leading to possible
conflicts. Our first to choice to solve such conflicts
was to use $ but that's not a valid variable name in core.
Therefore we picked @ which is currently supported and
still reduces the chance of conflicts.
|
|
It is possible that '...' is added later (OTP 20.0), but for now we
are not sure of all details.
|
|
* stavros/dialyzer/fix_call_site_analysis/OTP-13655/PR-1092:
Fix a bug in Dialyzer related to call-site analysis
|
|
Dialyzer's "dataflow" module is using information from the callgraph to
determine which functions may be called at a particular call-site. Unfortunately
this information can include functions that are certainly not among the possible
choices. We don't want to emit warnings in such cases, so a "reasonable"
compromise is to stay silent if there are many possible funs and at least one of
them can succeed.
Bug reported by Dan Gudmundsson, test shrunk down by Magnus Lång.
|
|
Dialyzer failed to remove all loops among constraints.
|
|
|
|
Dialyzer relies heavily on the assumption that the type of a literal
that is used as a pattern is the type of any value that can match that
pattern. For maps, that is not true, and it was causing bad analysis
results. A new help function dialyzer_utils:refold_pattern/1 identifies
maps in literal patterns, and unfolds and labels them, allowing them to
be properly analysed.
|
|
|
|
|
|
* maps:from_list/1
* maps:get/2
* maps:is_key/2
* maps:merge/2
* maps:put/3
* maps:size/1
* maps:to_list/1
* maps:update/3
|
|
The type of a map is represented as a three-tuple {Pairs, DefaultKey,
DefaultValue}. DefaultKey and DefaultValue are types. Pairs is a list of
three-tuples {Key, mandatory | optional, Value}, where Key and Value are
types. All types Key must be singleton, or "known at compile time," as
the EEP put it. Examples:
#{integer()=>list()} {[], integer(), list()}
#{a=>char(), b=>atom()} {[{a, optional, char()},
{b, optional, atom()}],
none(), none()}
map() {[], any(), any()}
A more formal description of the representation and its invariants can
be found in erl_types.erl
Special thanks to Daniel S. McCain (@dsmccain) that co-authored a very
early version of this with me back in April 2014, although only the
singleton type logic remains from that version.
|
|
|
|
* maint:
dialyzer: Correct byte_size() and comparisons
Conflicts:
lib/hipe/cerl/erl_bif_types.erl
|
|
The argument of byte_size() is a bitstring().
The code in erl_bif_types that finds cases where comparisons always
return true or false is corrected when it comes to maps and bit
strings.
|
|
Parameterized modules are no longer supported, so module() can only be
an atom().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* lucafavatella/dialyzer-fun-literal-arity:
Teach Dialyzer arity of funs with literal arity
OTP-13068
|
|
Background
-----------
In record fields with a type declaration but without an initializer, the
Erlang parser inserted automatically the singleton type 'undefined' to
the list of declared types, if that value was not present there.
I.e. the record declaration:
-record(rec, {f1 :: float(),
f2 = 42 :: integer(),
f3 :: some_mod:some_typ()}).
was translated by the parser to:
-record(rec, {f1 :: float() | 'undefined',
f2 = 42 :: integer(),
f3 :: some_mod:some_typ() | 'undefined'}).
The rationale for this was that creation of a "dummy" #rec{} record
should not result in a warning from dialyzer that e.g. the implicit
initialization of the #rec.f1 field violates its type declaration.
Problems
---------
This seemingly innocent action has some unforeseen consequences.
For starters, there is no way for programmers to declare that e.g. only
floats make sense for the f1 field of #rec{} records when there is no
`obvious' default initializer for this field. (This also affects tools
like PropEr that use these declarations produced by the Erlang parser to
generate random instances of records for testing purposes.)
It also means that dialyzer does not warn if e.g. an is_atom/1 test or
something more exotic like an atom_to_list/1 call is performed on the
value of the f1 field.
Similarly, there is no way to extend dialyzer to warn if it finds record
constructions where f1 is not initialized to some float.
Last but not least, it is semantically problematic when the type of the
field is an opaque type: creating a union of an opaque and a structured
type is very problematic for analysis because it fundamentally breaks
the opacity of the term at that point.
Change
-------
To solve these problems the parser will not automatically insert the
'undefined' value anymore; instead the user has the option to choose the
places where this value makes sense (for the field) and where it does
not and insert the | 'undefined' there manually.
Consequences of this change
----------------------------
This change means that dialyzer will issue a warning for all places
where records with uninitialized fields are created and those fields have
a declared type that is incompatible with 'undefined' (e.g. float()).
This warning can be suppressed easily by adding | 'undefined' to the
type of this field. This also adds documentation that the user really
intends to create records where this field is uninitialized.
|
|
The recently added module erl_anno can no longer handle
negative line numbers.
|
|
Fix the range type of erlang:abs/1.
|
|
Thanks to ILYA Khlopotov for pointing the bug out.
|
|
Re-insert logic for `erlang:make_fun/3` in `erl_bif_types`. It had
been removed in bd941f5 while type spec-ing `erlang.erl`. Type spec in
`erlang.erl` cannot express arity of returned fun based on value of
argument hence re-introducing logic in `erl_bif_types`.
Re-definition of logic in `erl_bif_types` follows approach in 9d870a0.
|
|
|
|
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.
|
|
* aronisstav/dialyzer-inv-mult:
Fix a bug related to constraints generated for erlang:'*'/2
OTP-12725
|
|
For Rst = A1 * A2, typesig for erlang:'*'/2 was constraining the
arguments A1 and A2 in the 'reverse' direction by requiring that A2 is a
subtype of Rst div A1, unless A1 is a hard zero. This is not correct: if
for example both Rst and A1 are non_negative, such a constraint will
first force A1 to be non-zero for the division to go through and then
require A2 to be non_negative as non_negative div positive =
non_negative, always (see commited test).
In the fixed version, we are not constraining an argument if the other
operand *may* be zero.
|
|
|
|
Replace the undocumented option 'no_unknown' with the documented
option 'unknown'.
|
|
|
|
The tests cannot be handled by earlier versions of Dialyzer.
|
|
In particular fix handling of records.
|