diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index 2dccbf5061..3f786dc779 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -3000,8 +3000,12 @@ defmodule Module.Types.Descr do end end - defp map_union_strategy([], [], _tag1, _tag2, status) do - status + defp map_union_strategy([], [], tag1, tag2, status) do + case status do + :left_subtype_of_right when tag1 == :open and tag2 == :closed -> :none + :right_subtype_of_left when tag1 == :closed and tag2 == :open -> :none + _ -> status + end end defp map_union_strategy(l1, l2, tag1, tag2, status) do diff --git a/lib/elixir/test/elixir/module/types/descr_test.exs b/lib/elixir/test/elixir/module/types/descr_test.exs index 7a0a3f3d72..ee3882ae0c 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -115,6 +115,14 @@ defmodule Module.Types.DescrTest do a_integer_open = open_map(a: integer()) assert equal?(union(closed_map(a: integer()), a_integer_open), a_integer_open) + closed = closed_map(a: integer(), b: atom()) + open = open_map(a: integer(), b: boolean()) + + assert subtype?(closed, union(closed, open)) + assert subtype?(open, union(closed, open)) + assert subtype?(closed, union(open, closed)) + assert subtype?(open, union(open, closed)) + # Domain key types atom_to_atom = open_map([{domain_key(:atom), atom()}]) atom_to_integer = open_map([{domain_key(:atom), integer()}])