aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/test/map_SUITE_data/src/opaque_key/opaque_key_adt.erl
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2016-04-18 19:19:23 +0200
committerHans Bolinder <[email protected]>2016-04-28 16:16:10 +0200
commitd2ba8674603bc4ef210ec91e6f51924f7efe8c2e (patch)
tree3bf92f18425dcf38291ba452b3b322ae407cda55 /lib/dialyzer/test/map_SUITE_data/src/opaque_key/opaque_key_adt.erl
parent12f968890c34e2591e7d4d8797896878f6cb6c62 (diff)
downloadotp-d2ba8674603bc4ef210ec91e6f51924f7efe8c2e.tar.gz
otp-d2ba8674603bc4ef210ec91e6f51924f7efe8c2e.tar.bz2
otp-d2ba8674603bc4ef210ec91e6f51924f7efe8c2e.zip
erl_types: Fix crash merging maps with opaque keys
Opaque keys in maps broke an assumption in erl_types:mapmerge_otherv/3 (that the infinimum of a singleton type and some other type would either be none() or that same singleton type), causing a case_clause crash.
Diffstat (limited to 'lib/dialyzer/test/map_SUITE_data/src/opaque_key/opaque_key_adt.erl')
-rw-r--r--lib/dialyzer/test/map_SUITE_data/src/opaque_key/opaque_key_adt.erl69
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/dialyzer/test/map_SUITE_data/src/opaque_key/opaque_key_adt.erl b/lib/dialyzer/test/map_SUITE_data/src/opaque_key/opaque_key_adt.erl
new file mode 100644
index 0000000000..53ec09b062
--- /dev/null
+++ b/lib/dialyzer/test/map_SUITE_data/src/opaque_key/opaque_key_adt.erl
@@ -0,0 +1,69 @@
+-module(opaque_key_adt).
+
+-compile(export_all).
+
+-export_type([t/0, t/1, m/0, s/1, sm/1]).
+
+-opaque t() :: #{atom() => integer()}.
+-opaque t(A) :: #{A => integer()}.
+
+-opaque m() :: #{t() => integer()}.
+-type mt() :: #{t() => integer()}.
+
+-opaque s(K) :: #{K => integer(), integer() => atom()}.
+-opaque sm(K) :: #{K := integer(), integer() := atom()}.
+-type smt(K) :: #{K := integer(), integer() := atom()}.
+
+-spec t0() -> t().
+t0() -> #{}.
+
+-spec t1() -> t(integer()).
+t1() -> #{3 => 1}.
+
+-spec m0() -> m().
+m0() -> #{#{} => 3}.
+
+-spec mt0() -> mt().
+mt0() -> #{#{} => 3}.
+
+-spec s0() -> s(atom()).
+s0() -> #{}.
+
+-spec s1() -> s(atom()). %% No contract breakage (bad warning)
+s1() -> #{3 => a}.
+
+-spec s2() -> s(atom() | 3).
+s2() -> #{3 => a}. %% Contract breakage
+
+-spec s3() -> s(atom() | 3).
+s3() -> #{3 => 5, a => 6, 7 => 8}.
+
+-spec s4() -> s(integer()).
+s4() -> #{1 => a}. %% Actual contract breakage (good warning)
+
+-spec s5() -> s(1).
+s5() -> #{2 => 3}. %% Contract breakage (not found)
+
+-spec s6() -> s(1).
+s6() -> #{1 => 3}.
+
+-spec s7() -> s(integer()).
+s7() -> #{1 => 3}.
+
+-spec sm1() -> sm(1). %% No contract breakage (bad warning)
+sm1() -> #{1 => 2, 3 => a}.
+
+-spec smt1() -> smt(1).
+smt1() -> #{3 => a}. %% Contract breakage
+
+-spec smt2() -> smt(1).
+smt2() -> #{1 => a}. %% Contract breakage
+
+-spec smt3() -> smt(q).
+smt3() -> #{q => 1}. %% Slight contract breakage (probably requires better map type)
+
+-spec smt4() -> smt(q).
+smt4() -> #{q => 2, 3 => a}.
+
+-spec smt5() -> smt(1).
+smt5() -> #{1 => 2, 3 => a}.