Skip to content

Commit 16a1472

Browse files
authored
Refactor Descr.map_all_but_one (#14231)
1 parent 615751d commit 16a1472

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

lib/elixir/lib/module/types/descr.ex

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,7 +1862,7 @@ defmodule Module.Types.Descr do
18621862
if map_empty_negation?(tag, acc_fields, neg) do
18631863
{acc_fields, acc_negs}
18641864
else
1865-
case map_all_but_one?(tag, acc_fields, neg_tag, neg_fields) do
1865+
case map_all_but_one(tag, acc_fields, neg_tag, neg_fields) do
18661866
{:one, diff_key} ->
18671867
{Map.update!(acc_fields, diff_key, &difference(&1, neg_fields[diff_key])),
18681868
acc_negs}
@@ -1913,19 +1913,20 @@ defmodule Module.Types.Descr do
19131913
end
19141914

19151915
# If all fields are the same except one, we can optimize map difference.
1916-
defp map_all_but_one?(tag1, fields1, tag2, fields2) do
1917-
keys1 = Map.keys(fields1)
1918-
keys2 = Map.keys(fields2)
1919-
1920-
if {tag1, tag2} == {:open, :closed} or
1921-
:sets.from_list(keys1, version: 2) != :sets.from_list(keys2, version: 2) do
1922-
:no
1916+
defp map_all_but_one(tag1, fields1, tag2, fields2) do
1917+
with true <- {tag1, tag2} != {:open, :closed},
1918+
true <- map_size(fields1) == map_size(fields2),
1919+
keys = :maps.keys(fields1),
1920+
true <- Enum.all?(keys, fn key -> is_map_key(fields2, key) end),
1921+
1 <-
1922+
Enum.count_until(
1923+
keys,
1924+
fn key -> Map.fetch!(fields1, key) != Map.fetch!(fields2, key) end,
1925+
_limit = 2
1926+
) do
1927+
{:one, Enum.find(keys, &(Map.fetch!(fields1, &1) != Map.fetch!(fields2, &1)))}
19231928
else
1924-
Enum.count(keys1, fn key -> Map.get(fields1, key) != Map.get(fields2, key) end)
1925-
|> case do
1926-
1 -> {:one, Enum.find(keys1, &(Map.get(fields1, &1) != Map.get(fields2, &1)))}
1927-
_ -> :no
1928-
end
1929+
_ -> :no
19291930
end
19301931
end
19311932

0 commit comments

Comments
 (0)