Skip to content

Commit 63ed546

Browse files
committed
Deal with maps and tuples of none
1 parent 50d628c commit 63ed546

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ defmodule Module.Types.Descr do
14511451
Enum.all?(dnf, fn {tag, pos, negs} -> map_empty?(tag, pos, negs) end)
14521452
end
14531453

1454-
defp map_empty?(_, _, []), do: false
1454+
defp map_empty?(_, pos, []), do: Enum.any?(Map.to_list(pos), fn {_, v} -> empty?(v) end)
14551455
defp map_empty?(_, _, [{:open, neg_fields} | _]) when neg_fields == %{}, do: true
14561456
defp map_empty?(:open, fs, [{:closed, _} | negs]), do: map_empty?(:open, fs, negs)
14571457

@@ -1785,11 +1785,11 @@ defmodule Module.Types.Descr do
17851785
end
17861786

17871787
# No negations, so not empty
1788-
defp tuple_empty?(_, _, []), do: false
1788+
defp tuple_empty?(_, pos, []), do: Enum.any?(pos, &empty?/1)
17891789
# Open empty negation makes it empty
17901790
defp tuple_empty?(_, _, [{:open, []} | _]), do: true
17911791
# Open positive can't be emptied by a single closed negative
1792-
defp tuple_empty?(:open, _, [{:closed, _}]), do: false
1792+
defp tuple_empty?(:open, pos, [{:closed, _}]), do: Enum.any?(pos, &empty?/1)
17931793

17941794
defp tuple_empty?(tag, elements, [{neg_tag, neg_elements} | negs]) do
17951795
n = length(elements)
@@ -1801,21 +1801,21 @@ defmodule Module.Types.Descr do
18011801
if (tag == :closed and n < m) or (neg_tag == :closed and n > m) do
18021802
tuple_empty?(tag, elements, negs)
18031803
else
1804-
tuple_elements([], tag, elements, neg_elements, negs) and
1804+
tuple_elements_empty?([], tag, elements, neg_elements, negs) and
18051805
tuple_compatibility(n, m, tag, elements, neg_tag, negs)
18061806
end
18071807
end
18081808

18091809
# Recursively check elements for emptiness
1810-
defp tuple_elements(_, _, _, [], _), do: true
1810+
defp tuple_elements_empty?(_, _, _, [], _), do: true
18111811

1812-
defp tuple_elements(acc, tag, elements, [neg_type | neg_elements], negs) do
1812+
defp tuple_elements_empty?(acc, tag, elements, [neg_type | neg_elements], negs) do
18131813
# Handles the case where {tag, elements} is an open tuple, like {:open, []}
18141814
{ty, elements} = List.pop_at(elements, 0, term())
18151815
diff = difference(ty, neg_type)
18161816

18171817
(empty?(diff) or tuple_empty?(tag, Enum.reverse(acc, [diff | elements]), negs)) and
1818-
tuple_elements([ty | acc], tag, elements, neg_elements, negs)
1818+
tuple_elements_empty?([ty | acc], tag, elements, neg_elements, negs)
18191819
end
18201820

18211821
# Determines if the set difference is empty when:
@@ -2104,7 +2104,7 @@ defmodule Module.Types.Descr do
21042104
end
21052105

21062106
defp tuple_of_size_at_least(n) when is_integer(n) and n >= 0 do
2107-
open_tuple(List.duplicate(term(), n))
2107+
tuple_descr(:open, List.duplicate(term(), n))
21082108
end
21092109

21102110
defp tuple_of_size_at_least_static?(descr, index) do

lib/elixir/test/elixir/module/types/descr_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,9 @@ defmodule Module.Types.DescrTest do
544544

545545
describe "empty?" do
546546
test "tuple" do
547+
assert tuple([none()]) |> empty?()
548+
assert open_tuple([integer(), none()]) |> empty?()
549+
547550
assert intersection(tuple([integer(), atom()]), open_tuple([atom()])) |> empty?()
548551
refute open_tuple([integer(), integer()]) |> difference(empty_tuple()) |> empty?()
549552
refute open_tuple([integer(), integer()]) |> difference(open_tuple([atom()])) |> empty?()
@@ -563,6 +566,8 @@ defmodule Module.Types.DescrTest do
563566
end
564567

565568
test "map" do
569+
assert open_map(a: none()) |> empty?()
570+
assert closed_map(a: integer(), b: none()) |> empty?()
566571
assert intersection(closed_map(b: atom()), open_map(a: integer())) |> empty?()
567572
end
568573
end

0 commit comments

Comments
 (0)