Skip to content

Commit 03b45e5

Browse files
josevalimgldubc
andauthored
Remove redundant line empty when we eliminate negations (#15196)
Co-authored-by: Guillaume Duboc <guilduboc@gmail.com>
1 parent bcfefa1 commit 03b45e5

File tree

2 files changed

+17
-28
lines changed

2 files changed

+17
-28
lines changed

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

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5126,10 +5126,8 @@ defmodule Module.Types.Descr do
51265126
zip_empty_intersection?(elements, neg_elements) do
51275127
[{tag, elements}]
51285128
else
5129-
tuple_dnf_union(
5130-
tuple_elim_size(n, m, tag, elements, neg_tag),
5129+
tuple_elim_size(n, m, tag, elements, neg_tag) ++
51315130
tuple_elim_content([], tag, elements, neg_elements)
5132-
)
51335131
end
51345132
end
51355133

@@ -5207,19 +5205,6 @@ defmodule Module.Types.Descr do
52075205
end)
52085206
end
52095207

5210-
# Prefer the smaller on the left
5211-
defp tuple_dnf_union(dnf1, dnf2) do
5212-
# Union of tuple DNFs is just concatenation,
5213-
# but we do our best to remove duplicates.
5214-
with [tuple1] <- dnf1,
5215-
[tuple2] <- dnf2,
5216-
optimized when optimized != nil <- maybe_optimize_tuple_union(tuple1, tuple2) do
5217-
[optimized]
5218-
else
5219-
_ -> dnf1 ++ (dnf2 -- dnf1)
5220-
end
5221-
end
5222-
52235208
defp tuple_union(
52245209
bdd_leaf(tag1, elements1) = tuple1,
52255210
bdd_leaf(tag2, elements2) = tuple2
@@ -5313,23 +5298,17 @@ defmodule Module.Types.Descr do
53135298
end
53145299

53155300
# Transforms a bdd into a union of tuples with no negations.
5316-
# Note: it is important to compose the results with
5317-
# tuple_dnf_union/2 to avoid duplicates
53185301
defp tuple_bdd_to_dnf_no_negations(bdd) do
53195302
bdd_to_dnf(bdd)
5320-
|> Enum.reduce([], fn {pos, negs}, acc ->
5303+
|> Enum.flat_map(fn {pos, negs} ->
53215304
case non_empty_tuple_literals_intersection(pos) do
5322-
:empty ->
5323-
acc
5324-
5325-
{tag, elements} ->
5326-
if tuple_line_empty?(tag, elements, negs) do
5327-
acc
5328-
else
5329-
tuple_eliminate_negations(tag, elements, negs) |> tuple_dnf_union(acc)
5330-
end
5305+
:empty -> []
5306+
{tag, elements} -> tuple_eliminate_negations(tag, elements, negs)
53315307
end
53325308
end)
5309+
# We want to avoid each_singleton? from failing,
5310+
# so we remove contiguous duplicates (cheaper than uniq)
5311+
|> Enum.dedup()
53335312
end
53345313

53355314
defp tuple_bdd_to_dnf_with_negations(bdd) do

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,16 @@ defmodule Module.Types.DescrTest do
14301430
refute singleton?(open_tuple([]))
14311431
refute singleton?(union(tuple([atom([:value])]), tuple([atom([:other_value])])))
14321432
refute singleton?(union(tuple([atom([:value])]), closed_map(other: atom([:value]))))
1433+
1434+
# Both BDD lines produce the same singleton tuple, so the tuple DNF must not duplicate it.
1435+
a = tuple([union(integer(), atom([:ok])), atom([:x])])
1436+
b = tuple([integer(), atom([:x, :y])])
1437+
c = tuple([integer(), union(atom([:x]), binary())])
1438+
1439+
t = union(difference(a, b), difference(a, c))
1440+
# Semantically t ~= {:ok, :x}, confirmed by equal?
1441+
assert equal?(t, tuple([atom([:ok]), atom([:x])]))
1442+
assert singleton?(t)
14331443
end
14341444
end
14351445

0 commit comments

Comments
 (0)