From a84c447df7978ce3f9c94d4656f444f3f0fa83b2 Mon Sep 17 00:00:00 2001 From: Guillaume Duboc Date: Wed, 29 Apr 2026 00:35:33 +0200 Subject: [PATCH] Fix map union optimization for open maps --- lib/elixir/lib/module/types/descr.ex | 8 ++++++-- lib/elixir/test/elixir/module/types/descr_test.exs | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index 2dccbf50611..3f786dc7796 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 7a0a3f3d723..ee3882ae0ca 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()}])