Skip to content

Commit ec96574

Browse files
committed
Reuse fuse logic
1 parent 9d74860 commit ec96574

File tree

1 file changed

+8
-36
lines changed

1 file changed

+8
-36
lines changed

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

+8-36
Original file line numberDiff line numberDiff line change
@@ -1868,49 +1868,21 @@ defmodule Module.Types.Descr do
18681868

18691869
defp map_non_negated_fuse(maps) do
18701870
Enum.reduce(maps, [], fn map, acc ->
1871-
case Enum.split_while(acc, &non_fusible_maps?(map, &1)) do
1872-
{_, []} ->
1873-
[map | acc]
1874-
1875-
{others, [match | rest]} ->
1876-
fused = map_non_negated_fuse_pair(map, match)
1877-
others ++ [fused | rest]
1878-
end
1871+
fuse_with_first_fusible(map, acc)
18791872
end)
18801873
end
18811874

1882-
# Two maps are fusible if they differ in at most one element.
1883-
# Given they are of the same size, the side you traverse is not important.
1884-
defp non_fusible_maps?({_, fields1, []}, {_, fields2, []}) do
1885-
not fusible_maps?(Map.to_list(fields1), fields2, 0)
1886-
end
1875+
defp fuse_with_first_fusible(map, []), do: [map]
18871876

1888-
defp fusible_maps?([{:__struct__, value} | rest], fields, count) do
1889-
case Map.fetch!(fields, :__struct__) do
1890-
^value -> fusible_maps?(rest, fields, count)
1891-
_ -> false
1892-
end
1893-
end
1894-
1895-
defp fusible_maps?([{key, value} | rest], fields, count) do
1896-
case Map.fetch!(fields, key) do
1897-
^value -> fusible_maps?(rest, fields, count)
1898-
_ when count == 1 -> false
1899-
_ when count == 0 -> fusible_maps?(rest, fields, count + 1)
1877+
defp fuse_with_first_fusible(map, [candidate | rest]) do
1878+
if fused = maybe_optimize_map_union(map, candidate) do
1879+
# we found a fusible candidate, we're done
1880+
[fused | rest]
1881+
else
1882+
[candidate | fuse_with_first_fusible(map, rest)]
19001883
end
19011884
end
19021885

1903-
defp fusible_maps?([], _fields, _count), do: true
1904-
1905-
defp map_non_negated_fuse_pair({tag, fields1, []}, {_, fields2, []}) do
1906-
fields =
1907-
symmetrical_merge(fields1, fields2, fn _k, v1, v2 ->
1908-
if v1 == v2, do: v1, else: union(v1, v2)
1909-
end)
1910-
1911-
{tag, fields, []}
1912-
end
1913-
19141886
# If all fields are the same except one, we can optimize map difference.
19151887
defp map_all_but_one?(tag1, fields1, tag2, fields2) do
19161888
keys1 = Map.keys(fields1)

0 commit comments

Comments
 (0)