Skip to content

Commit 93734a5

Browse files
committed
Provide better tuple elimitation in differences
1 parent e581128 commit 93734a5

1 file changed

Lines changed: 18 additions & 16 deletions

File tree

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

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4842,29 +4842,31 @@ defmodule Module.Types.Descr do
48424842
do: bdd_negation(bdd2)
48434843

48444844
defp tuple_difference(bdd1, bdd2),
4845-
do: bdd_difference(bdd1, bdd2, &tuple_leaf_compare?/2)
4845+
do: bdd_difference(bdd1, bdd2, &tuple_leaf_compare/2)
48464846

4847-
defp tuple_leaf_compare?(bdd_leaf(tag1, elements1), bdd_leaf(tag2, elements2)) do
4848-
if mismatched_tuple_sizes?(tag1, elements1, tag2, elements2) or
4849-
disjoint_tagged_tuples?(elements1, elements2) do
4847+
defp tuple_leaf_compare(bdd_leaf(tag1, elements1), bdd_leaf(tag2, elements2)) do
4848+
if mismatched_tuple_sizes?(tag1, elements1, tag2, elements2) do
48504849
:disjoint
48514850
else
4852-
:none
4851+
tuple_leaf_compare(elements1, elements2, tag1, tag2)
48534852
end
48544853
end
48554854

4856-
# A very cheap check for tagged tuples
4857-
defp disjoint_tagged_tuples?([%{atom: atom} = d1 | _], [d2 | _]) when map_size(d1) == 1,
4858-
do: disjoint_atom_descr?(atom, d2)
4859-
4860-
defp disjoint_tagged_tuples?([d1 | _], [%{atom: atom} = d2 | _]) when map_size(d2) == 1,
4861-
do: disjoint_atom_descr?(atom, d1)
4862-
4863-
defp disjoint_tagged_tuples?(_, _), do: false
4855+
defp tuple_leaf_compare([head1 | tail1], [head2 | tail2], tag1, tag2) do
4856+
cond do
4857+
disjoint?(head1, head2) -> :disjoint
4858+
subtype?(head1, head2) -> tuple_leaf_compare(tail1, tail2, tag1, tag2)
4859+
true -> :none
4860+
end
4861+
end
48644862

4865-
defp disjoint_atom_descr?(_atom, :term), do: false
4866-
defp disjoint_atom_descr?(atom1, %{atom: atom2}), do: atom_intersection(atom1, atom2) === 0
4867-
defp disjoint_atom_descr?(_atom, %{}), do: true
4863+
defp tuple_leaf_compare(tail1, tail2, tag1, tag2) do
4864+
cond do
4865+
tail1 == [] and tail2 == [] and (tag1 == :closed or tag1 == tag2) -> :subtype
4866+
tail1 != [] and tag2 == :open -> :subtype
4867+
true -> :none
4868+
end
4869+
end
48684870

48694871
defp non_empty_tuple_literals_intersection(tuples) do
48704872
try do

0 commit comments

Comments
 (0)