Age | Commit message (Collapse) | Author |
|
The clause added for maps in commit 1a7c41be is corrected.
|
|
Replace integers and floats with t_number() since keysearch et al
compare the key (rather than match).
Corrects the commit b3c8e94.
|
|
The existing test/0 function in erl_types was not being run in the OTP test
suite, and it had not been updated to match the implementation in the
module (maps vs. dict). This commit removes the macros that excluded some
functions, exports the functions now included in the module, and extracts the
test into a new common_test suite, erl_types_SUITE.
|
|
Rationale
Today all compound data types except for maps can be deconstructed in guards.
For tuples we have `element/2` and for lists `hd/1` and `tl/1`. Maps are
completely opaque to guards. This means matching on maps can't be
abstracted into macros, which is often done with repetitive guards. It
also means that maps have to be always selected whole from ETS tables,
even when only one field would be enough, which creates a potential
efficiency issue.
This PR introduces an `erlang:map_get/2` guard-safe function that allows
extracting a map field in guard. An alternative to this function would be
to introduce the syntax for extracting a value from a map that was planned
in the original EEP: `Map#{Key}`.
Even outside of guards, since this function is a guard-BIF it is more
efficient than using `maps:get/2` (since it does not need to set up the
stack), and more convenient from pattern matching on the map (compare:
`#{key := Value} = Map, Value` to `map_get(key, Map)`).
Performance considerations
A common concern against adding this function is the notion that "guards
have to be fast" and ideally execute in constant time. While there are
some counterexamples (`length/1`), what is more important is the fact
that adding those functions does not change in any way the time
complexity of pattern matching - it's already possible to match on map
fields today directly in patterns - adding this ability to guards will
niether slow down or speed up the execution, it will only make certain
programs more convenient to write.
This first version is very naive and does not perform any optimizations.
|
|
* maint:
dialyzer: Fix bsl/2 bug
|
|
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.
|
|
* maint:
dialyzer: Extend the map implementation's handling of ?unit
dialyzer: Use string:find() instead of string:str()
|
|
The Maps implementation handles ?unit in more cases.
Exactly when t_is_none_or_unit() is to be called is not clear to me.
The added cases are about a map type being ?unit, but the key or the
value of an association can also be ?unit, but that is not always
checked.
|
|
* maint:
dialyzer: Adjust a test case
dialyzer: Modify handling of singleton map key types
Dialyzer: Rewrite one map type invariant
Dialyzer: Rewrite some of the docs of map types
|
|
* hasse/dialyzer/map_fixes/OTP-14572:
dialyzer: Adjust a test case
dialyzer: Modify handling of singleton map key types
Dialyzer: Rewrite one map type invariant
Dialyzer: Rewrite some of the docs of map types
|
|
* siri/string-new-api: (28 commits)
hipe (test): Do not use deprecated functions in string(3)
dialyzer (test): Do not use deprecated functions in string(3)
eunit (test): Do not use deprecated functions in string(3)
system (test): Do not use deprecated functions in string(3)
system (test): Do not use deprecated functions in string(3)
mnesia (test): Do not use deprecated functions in string(3)
Deprecate old string functions
observer: Do not use deprecated functions in string(3)
common_test: Do not use deprecated functions in string(3)
eldap: Do not use deprecated functions in string(3)
et: Do not use deprecated functions in string(3)
os_mon: Do not use deprecated functions in string(3)
debugger: Do not use deprecated functions in string(3)
runtime_tools: Do not use deprecated functions in string(3)
asn1: Do not use deprecated functions in string(3)
compiler: Do not use deprecated functions in string(3)
sasl: Do not use deprecated functions in string(3)
reltool: Do not use deprecated functions in string(3)
kernel: Do not use deprecated functions in string(3)
hipe: Do not use deprecated functions in string(3)
...
Conflicts:
lib/eunit/src/eunit_lib.erl
lib/observer/src/crashdump_viewer.erl
lib/reltool/src/reltool_target.erl
|
|
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.
|
|
The test case loop.erl shows that there is a problem with certain
singleton key types. Here the internal representation toggles between
#{a | b => ...} and #{a => ..., b => ...}
The choice is to turn #{a | b => ...} into #{a => ..., b => ...} early
(t_from_form()). The aim is to keep as much info as possible (in
pairs). However, including complex singleton keys (tuples, maps) in
this scheme is potentially too costly, and a bit complicated. So one
more choice is made: let atoms and number (and nothing else) be
singleton types, and let complex keys go into the default key.
|
|
|
|
|
|
|
|
Substitute try/catch for an obsoletely used catch.
Thanks to Kostis for pointing it out.
|
|
|
|
|
|
|
|
As of commit 854ee8b (Erlang/OTP 18) warnings about using '_' as type
variable in parameterized types have not been output.
The code of erl_types:t_var_names() is corrected. The spec is also
corrected (thanks to Kostis for pointing out the bug).
|
|
* maint:
dialyzer: Improve a warning
dialyzer: Fix a weird warning
dialyzer: Fix an opaque bug
dialyzer: Minor fix
Conflicts:
lib/dialyzer/src/dialyzer_dataflow.erl
|
|
When a pattern a type do not match, opaque warnings were given
precedence before structure mismatches.
This is no longer always the case.
Mentioned by Nick Marino on erlang-questions.
|
|
|
|
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: Increase time limit for tests
dialyzer: Optimize typesig
dialyzer: Optimize evaluation of complex code
dialyzer: Optimize collection of variables
Conflicts:
lib/dialyzer/src/dialyzer_typesig.erl
|
|
|
|
* 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
|
|
|
|
* maint:
dialyzer: Fix check of parameterized opaque types
Conflicts:
lib/hipe/cerl/erl_types.erl
|
|
* hasse/dialyzer/fix_opaque_parms/OTP-14130:
dialyzer: Fix check of parameterized opaque types
|
|
* maint:
stdlib: Allow characters in types and constant patterns
|
|
Two parameters used to be "compatible" if one is a specialization of
the other, in the way that the input type of t_limit() is a
specialization of the output type. This check is now relaxed: any() in
any of the two parameters is compatible with any type of the other
parameter.
The change is due to bugus warnings.
A clause for maps has been added.
|
|
Characters ($char) can be used in constant pattern expressions. They
can also be used in types and contracts.
|
|
|
|
|
|
Suggested by Kostis.
|
|
The "decoration" of opaque types works better than before when opaque
types are used by other opaque types.
|
|
t_from_form() sometimes returned a more general type than it should
have done due to a bug in from_form_loop(): it stopped when the limit
was exceeded, which could mean a collapsed type. Returning a type with
smaller depth should fix this.
is_specialization() now handles opaque types before unions, which
should fix another problem.
The bugs reported by Kostis.
|
|
into maint
* margnus1/dialyzer/fix_maps_opaque/ERL-249/PR-1161/OTP-13878:
erl_bif_types: Properly unopaque maps:merge/2 args
|
|
erl_bif_types:type/5 was calling erl_types:map_pairwise_merge/3 directly
with its (potentially opaque) arguments, causing Dialyzer crashes.
Bug (ERL-249) reported and minimised test case provided by Felipe
Ripoll.
|
|
|
|
Fix a mistake in commit 85f6fe3b.
Instead of using the declared opaque type, the form's type is used in
a case where the opaque type is turned into a non-opaque type. The
result is more general types (smaller Erlang terms) and faster
analyses.
|
|
t_map/3 previously required callers to perform this normalisation, but
as t_from_form/5 would sometimes fail to do so, this requirement is
relaxed.
Bug (ERL-177) reported and shrunk by Luke Imhoff.
|
|
* hasse/dialyzer/improve_from_form/OTP-13547:
Update primary bootstrap
stdlib: Correct types and specs
dialyzer: Minor adjustments
dialyzer: Suppress unmatched_return for send/2
dialyzer: Improve the translation of forms to types
dialyzer: Use a cache when translating forms to types
dialyzer: Prepare erl_types:t_from_form() for a cache
dialyzer: Optimize erl_types:t_form_form()
dialyzer: Correct types
syntax_tools: Correct types
erts: Correct character repr in doc of the abstract format
stdlib: Correct types and specs
|
|
It is possible that '...' is added later (OTP 20.0), but for now we
are not sure of all details.
|
|
Spend less of the limited resources on recursive types.
|
|
|
|
No change of functionality.
|
|
When the translation from forms to types exceeds some limit, it is
faster to try small depths first.
|