diff options
author | Björn Gustavsson <[email protected]> | 2018-08-10 07:43:31 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-08-13 09:26:36 +0200 |
commit | 7e1eb2ed1f724945884d839bd8a99154e9382849 (patch) | |
tree | 42dd357548847ad0197c825157a2b091838a6099 /bin | |
parent | 77d307e6c3e705e14843101d4c5348c6c079ace0 (diff) | |
download | otp-7e1eb2ed1f724945884d839bd8a99154e9382849.tar.gz otp-7e1eb2ed1f724945884d839bd8a99154e9382849.tar.bz2 otp-7e1eb2ed1f724945884d839bd8a99154e9382849.zip |
Correct error behavior of is_map_key/2 in guards
Consider the following functions:
foo() -> bar(not_a_map).
bar(M) when not is_map_key(a, M) -> ok;
bar(_) -> error.
What will `foo/0` return? It depends. If the module is compiled
with the default compiler options, the return value will be
`ok`. If the module is compiled with the `inline` option,
the return value will be `error`.
The correct value is `error`, because the call to `is_map_key/2`
when the second argument is not a map should fail the entire
guard. That is the way other failing guards BIFs are handled.
For example:
foo() -> bar(not_a_tuple).
bar(T) when not element(1, T) -> ok;
bar(_) -> error.
`foo/0` always returns `error` (whether the code is inlined
or not).
This bug can be fixed by changing the classification of `is_map_key/2`
in the `erl_internal` module. It is now classified as a type test,
which is incorrect because type tests should not fail. Reclassifying
it as a plain guard BIF corrects the bug.
This correction also fixes the internal consistency check
failure which was reported in:
https://bugs.erlang.org/browse/ERL-699
Diffstat (limited to 'bin')
0 files changed, 0 insertions, 0 deletions