File 0770-dialyzer-Handle-maps-remove-2-better.patch of Package erlang

From 212a5ef0e2a0b38be365c098ddb4c8b9c5a1cd22 Mon Sep 17 00:00:00 2001
From: Hans Bolinder <hasse@erlang.org>
Date: Mon, 9 Sep 2019 15:46:48 +0200
Subject: [PATCH] dialyzer: Handle maps:remove/2 better

See also ERL-1002.
---
 .../test/map_SUITE_data/results/maps_remove        |  4 ++++
 .../test/map_SUITE_data/src/maps_remove.erl        | 23 ++++++++++++++++++++++
 lib/hipe/cerl/erl_bif_types.erl                    |  8 ++++++++
 lib/hipe/cerl/erl_types.erl                        | 22 +++++++++++++++++++++
 lib/stdlib/src/maps.erl                            |  3 ++-
 5 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 lib/dialyzer/test/map_SUITE_data/results/maps_remove
 create mode 100644 lib/dialyzer/test/map_SUITE_data/src/maps_remove.erl

diff --git a/lib/dialyzer/test/map_SUITE_data/results/maps_remove b/lib/dialyzer/test/map_SUITE_data/results/maps_remove
new file mode 100644
index 0000000000..32e43466b0
--- /dev/null
+++ b/lib/dialyzer/test/map_SUITE_data/results/maps_remove
@@ -0,0 +1,4 @@
+
+maps_remove.erl:22: Function get/2 has no local return
+maps_remove.erl:23: The call maps:get(K::'a',M::#{}) will never return since the success typing arguments are (any(),map())
+maps_remove.erl:7: Function t1/0 has no local return
diff --git a/lib/dialyzer/test/map_SUITE_data/src/maps_remove.erl b/lib/dialyzer/test/map_SUITE_data/src/maps_remove.erl
new file mode 100644
index 0000000000..b913e389f8
--- /dev/null
+++ b/lib/dialyzer/test/map_SUITE_data/src/maps_remove.erl
@@ -0,0 +1,23 @@
+%% ERL-1002, maps:remove
+
+-module(maps_remove).
+
+-export([t1/0]).
+
+t1() ->
+    A = new(),
+    B = put(a, 1, A),
+    C = remove(a, B),
+    get(a, C).
+
+new() ->
+    maps:new().
+
+put(K, V, M) ->
+    maps:put(K, V, M).
+
+remove(K, M) ->
+    maps:remove(K, M).
+
+get(K, M) ->
+    maps:get(K, M).
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 8ae1cd4ab7..ded93211fa 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -115,6 +115,7 @@
 		    t_map_is_key/3,
 		    t_map_entries/2,
 		    t_map_put/3,
+		    t_map_remove/3,
 		    t_map_update/3,
 		    t_map_pairwise_merge/4
 		   ]).
@@ -1691,6 +1692,11 @@ type(maps, put, 3, Xs, Opaques) ->
 	 fun ([Key, Value, Map]) ->
 	     t_map_put({Key, Value}, Map, Opaques)
 	 end, Opaques);
+type(maps, remove, 2, Xs, Opaques) ->
+  strict(maps, remove, 2, Xs,
+         fun ([Key, Map]) ->
+             t_map_remove(Key, Map, Opaques)
+         end, Opaques);
 type(maps, size, 1, Xs, Opaques) ->
   strict(maps, size, 1, Xs,
 	 fun ([Map]) ->
@@ -2652,6 +2658,8 @@ arg_types(maps, merge, 2) ->
   [t_map(), t_map()];
 arg_types(maps, put, 3) ->
   [t_any(), t_any(), t_map()];
+arg_types(maps, remove, 2) ->
+  [t_any(), t_map()];
 arg_types(maps, size, 1) ->
   [t_map()];
 arg_types(maps, to_list, 1) ->
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index badf58936f..5f5612fcd3 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -154,6 +154,7 @@
 	 t_map_update/2, t_map_update/3,
 	 t_map_pairwise_merge/4,
 	 t_map_put/2, t_map_put/3,
+         t_map_remove/3,
 	 t_matchstate/0,
 	 t_matchstate/2,
 	 t_matchstate_present/1,
@@ -1925,6 +1926,27 @@ map_put({Key, Value}, ?map(Pairs,DefK,DefV), Opaques) ->
       end
   end.
 
+-spec t_map_remove(erl_type(), erl_type(), opaques()) -> erl_type().
+
+t_map_remove(Key, Map, Opaques) ->
+  do_opaque(Map, Opaques, fun(UM) -> map_remove(Key, UM) end).
+
+map_remove(_, ?none) -> ?none;
+map_remove(_, ?unit) -> ?none;
+map_remove(Key, Map) ->
+  %% ?map(lists:keydelete(Key, 1, Pairs), DefK, DefV).
+  case is_singleton_type(Key) of
+    false -> Map;
+    true ->
+      ?map(Pairs,DefK,DefV) = Map,
+      case lists:keyfind(Key, 1, Pairs) of
+        false -> Map;
+        {Key, _, _} ->
+          Pairs1 = lists:keydelete(Key, 1, Pairs),
+          t_map(Pairs1, DefK, DefV)
+      end
+  end.
+
 -spec t_map_update({erl_type(), erl_type()}, erl_type()) -> erl_type().
 
 t_map_update(KV, Map) ->
diff --git a/lib/stdlib/src/maps.erl b/lib/stdlib/src/maps.erl
index 51965ddb57..49d6a12eb2 100644
--- a/lib/stdlib/src/maps.erl
+++ b/lib/stdlib/src/maps.erl
@@ -95,6 +95,7 @@ merge(_,_) -> erlang:nif_error(undef).
 put(_,_,_) -> erlang:nif_error(undef).
 
 
+%% Shadowed by erl_bif_types: maps:remove/2
 -spec remove(Key,Map1) -> Map2 when
     Key :: term(),
     Map1 :: map(),
-- 
2.16.4

openSUSE Build Service is sponsored by