Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions lib/elixir/lib/module/types/descr.ex
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,11 @@ defmodule Module.Types.Descr do
defp pop_dynamic(:term), do: {:term, :term}
defp pop_dynamic(descr), do: Map.pop(descr, :dynamic, descr)

defp put_dynamic(:term, dynamic), do: optional_to_term(%{dynamic: dynamic})
defp put_dynamic(static, dynamic) when static == dynamic, do: static
defp put_dynamic(_static, dynamic) when dynamic == @none, do: @none
defp put_dynamic(static, dynamic), do: Map.put(static, :dynamic, dynamic)

@doc """
Computes the union of two descrs.
"""
Expand Down Expand Up @@ -502,7 +507,8 @@ defmodule Module.Types.Descr do
{right_dynamic, right_static} = pop_dynamic(right)
dynamic_part = bare_difference_static(left_dynamic, right_static)

Map.put(bare_difference_static(left_static, right_dynamic), :dynamic, dynamic_part)
bare_difference_static(left_static, right_dynamic)
|> put_dynamic(dynamic_part)
else
bare_difference_static(left, right)
end
Expand Down Expand Up @@ -6125,7 +6131,8 @@ defmodule Module.Types.Descr do
{right_dynamic, right_static} = pop_dynamic(right)
dynamic_part = opt_difference_static(left_dynamic, right_static)

Map.put(opt_difference_static(left_static, right_dynamic), :dynamic, dynamic_part)
opt_difference_static(left_static, right_dynamic)
|> put_dynamic(dynamic_part)
else
opt_difference_static(left, right)
end
Expand Down
6 changes: 5 additions & 1 deletion lib/elixir/test/elixir/module/types/descr_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,10 @@ defmodule Module.Types.DescrTest do
assert equal?(dynamic(), opt_difference(term(), dynamic()))
assert empty?(opt_difference(dynamic(), term()))
assert empty?(opt_difference(none(), dynamic()))
assert empty?(opt_difference(dynamic(integer()), integer()))
assert opt_difference(dynamic(integer()), integer()) == none()

# Covers assembling a result with static :term and dynamic unfolded term.
assert opt_difference(term(), %{dynamic: none(), optional: 1}) == term()
end

test "tuple" do
Expand Down Expand Up @@ -3336,6 +3339,7 @@ defmodule Module.Types.DescrTest do

test "dynamic (negation)" do
assert dynamic(opt_negation(integer())) |> to_quoted_string() == "dynamic(not integer())"
assert opt_negation(dynamic(none())) == term()

assert opt_negation(dynamic(integer())) |> to_quoted_string() ==
"dynamic() or not integer()"
Expand Down
Loading