Skip to content

Commit 9add533

Browse files
committed
Avoid cascading unions in map difference
1 parent 27aadff commit 9add533

2 files changed

Lines changed: 21 additions & 9 deletions

File tree

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5632,11 +5632,13 @@ defmodule Module.Types.Descr do
56325632
when is_tuple(bdd2) do
56335633
case leaf_compare.(a1, bdd2) do
56345634
:disjoint ->
5635-
bdd_union(
5636-
bdd_difference(u1, bdd2, leaf_compare),
5637-
bdd_difference({a1, :bdd_bot, :bdd_bot, d1}, bdd2)
5638-
)
5639-
|> bdd_union({a1, c1, :bdd_bot, :bdd_bot})
5635+
res =
5636+
bdd_union(
5637+
bdd_difference(u1, bdd2, leaf_compare),
5638+
bdd_difference({a1, :bdd_bot, :bdd_bot, d1}, bdd2)
5639+
)
5640+
5641+
if c1 == :bdd_bot, do: res, else: bdd_union(res, {a1, c1, :bdd_bot, :bdd_bot})
56405642

56415643
:subtype ->
56425644
bdd_union(bdd_difference(u1, bdd2, leaf_compare), bdd_difference(d1, bdd2, leaf_compare))

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -620,11 +620,21 @@ defmodule Module.Types.DescrTest do
620620
assert difference(closed_map(__struct__: atom_foo), closed_map(__struct__: atom_bar)) ==
621621
closed_map(__struct__: atom_foo)
622622

623-
refute difference(closed_map(__struct__: atom_foo), closed_map(__struct__: term())) ==
624-
closed_map(__struct__: atom_foo)
623+
assert difference(closed_map(__struct__: atom_foo), closed_map(__struct__: term())) ==
624+
none()
625625

626-
refute difference(closed_map(__struct__: atom()), closed_map(__struct__: atom_bar)) ==
627-
closed_map(__struct__: atom())
626+
assert difference(closed_map(__struct__: atom()), closed_map(__struct__: atom_bar)) ==
627+
closed_map(__struct__: difference(atom(), atom_bar))
628+
629+
# Explicitly assert we keep it as cascading differences
630+
assert %{map: {{:closed, _}, :bdd_bot, :bdd_bot, _}} =
631+
difference(
632+
difference(
633+
open_map(value: term()),
634+
closed_map(__struct__: atom_foo, value: term())
635+
),
636+
closed_map(__struct__: atom_bar, name: term())
637+
)
628638
end
629639

630640
test "map with domain keys" do

0 commit comments

Comments
 (0)