diff options
author | Hans Bolinder <[email protected]> | 2015-08-21 11:54:30 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2015-08-21 12:03:16 +0200 |
commit | d57dea02cc2196ff6160471d06297413af5e20f2 (patch) | |
tree | 81144874ea0163b1bb00ada42285d21d1843e062 /lib/dialyzer/test/small_SUITE_data | |
parent | 6633afcb23e36c77cab56f18a4d327b368513e48 (diff) | |
download | otp-d57dea02cc2196ff6160471d06297413af5e20f2.tar.gz otp-d57dea02cc2196ff6160471d06297413af5e20f2.tar.bz2 otp-d57dea02cc2196ff6160471d06297413af5e20f2.zip |
hipe/dialyzer: Fix a bug concerning opaque types and keydelete/3
Thanks to ILYA Khlopotov for pointing the bug out.
Diffstat (limited to 'lib/dialyzer/test/small_SUITE_data')
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/src/keydel.erl | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/dialyzer/test/small_SUITE_data/src/keydel.erl b/lib/dialyzer/test/small_SUITE_data/src/keydel.erl new file mode 100644 index 0000000000..18a5c0670c --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/keydel.erl @@ -0,0 +1,29 @@ +-module(keydel). + +-export([store/3]). + +-record(att, {f}). + +-type attachment() :: list(). + +-opaque att() :: #att{} | attachment(). + +-spec store(atom(), any(), att()) -> att(). +store(Field, undefined, Att) when is_list(Att) -> + lists:keydelete(Field, 1, Att); +store(Field, Value, Att) when is_list(Att) -> + lists:keystore(Field, 1, Att, {Field, Value}); +store(Field, Value, Att) -> + store(Field, Value, upgrade(Att)). + + +-spec upgrade(#att{}) -> attachment(). +upgrade(#att{} = Att) -> + Map = lists:zip( + record_info(fields, att), + lists:seq(2, record_info(size, att)) + ), + %% Don't store undefined elements since that is default + [{F, element(I, Att)} || {F, I} <- Map, element(I, Att) /= undefined]; +upgrade(Att) -> + Att. |