diff options
author | Björn Gustavsson <[email protected]> | 2015-01-20 11:05:28 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-01-26 13:09:29 +0100 |
commit | 142da57a6790e879f0e593f97cf5a65459693c34 (patch) | |
tree | 5778be0ef4e58470f9b7200d0556d57277a5e647 /lib/compiler/src/sys_pre_attributes.erl | |
parent | 3ebfb44a83fcfd506fe4e4925412a973a86474ed (diff) | |
download | otp-142da57a6790e879f0e593f97cf5a65459693c34.tar.gz otp-142da57a6790e879f0e593f97cf5a65459693c34.tar.bz2 otp-142da57a6790e879f0e593f97cf5a65459693c34.zip |
cerl: Make sure that we preserve the invariants for maps
Maps have certain invariants that must be preserved:
(1) A map as a pattern must be represented as #c_map{} record,
never as a literal. The reason is that the pattern '#{}' will
match any map, not just the empty map. The literal '#{}' will
only match the empty map.
(2) In a map pattern, the key must be a literal, a variable, or
data (list or tuple). Keys that are binaries or maps *must* be
represented as literals.
(3) Maps in expressions should be represented as literals if possible.
Nothing is broken if this invariant is broken, but the generated
code will be less efficient.
To preserve invariant (1), cerl:update_c_map/3 must never collapse
a map to a literal. To preserve invariant (3), cerl:update_c_map/3
must collapse a map to a literal if possible.
To preserve both invariants, we need a way for cerl:update_c_map/3 to
know whether the map is used as a pattern or as an expression. The
simplest way is to have an 'is_pat' boolean in the #c_map{} record
which is set when a #c_map{} record is initially created.
We also need to update core_parse.yrl to establish the invariants
in the same way as v3_core, to ensure that compiling from a
.core file will work even if all optimizations on Core Erlang are
disabled.
Diffstat (limited to 'lib/compiler/src/sys_pre_attributes.erl')
0 files changed, 0 insertions, 0 deletions