From a3008f250a75bfefa0c42efb6e5b7e5237d9d49d Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Sun, 12 Jul 2026 10:37:38 +0200 Subject: [PATCH 1/3] Do not return `{:ok, _}` on maps with empty lines in `map_put_static_value` --- lib/elixir/lib/module/types/descr.ex | 2 +- lib/elixir/test/elixir/module/types/descr_test.exs | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index 5bee8403ed..2b4f8185f1 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -3897,7 +3897,7 @@ defmodule Module.Types.Descr do defp map_put_static_value(descr, split_keys, type) do case :maps.take(:dynamic, descr) do :error -> - if descr_key?(descr, :map) and map_only?(descr) do + if non_empty_map_only?(descr) do {:ok, map_put_static(descr, split_keys, type)} else :badmap diff --git a/lib/elixir/test/elixir/module/types/descr_test.exs b/lib/elixir/test/elixir/module/types/descr_test.exs index 70adcf749e..a4b473a90a 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -3334,6 +3334,16 @@ defmodule Module.Types.DescrTest do assert map_put(map, atom([:k]), binary()) == {:ok, open_map(k: binary(), x: term())} end + + test "verdict is stable across representations of an empty type" do + # An empty map component that survives syntactically (open_map(c: none()) + # is a non-normalized empty, equal to none()) must report :badmap like + # none(), not {:ok, }. + a2 = open_map(c: none()) + assert equal?(none(), a2) + assert map_put(none(), atom([:a]), integer()) == :badmap + assert map_put(a2, atom([:a]), integer()) == :badmap + end end describe "disjoint" do From a73f3788d385cda15cbd75dec1c6081a9f5bf783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 25 Jul 2026 17:57:30 +0200 Subject: [PATCH 2/3] Apply suggestion from @josevalim --- lib/elixir/test/elixir/module/types/descr_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir/test/elixir/module/types/descr_test.exs b/lib/elixir/test/elixir/module/types/descr_test.exs index a4b473a90a..5f3ca3e7da 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -3335,7 +3335,7 @@ defmodule Module.Types.DescrTest do assert map_put(map, atom([:k]), binary()) == {:ok, open_map(k: binary(), x: term())} end - test "verdict is stable across representations of an empty type" do + test "is consistent across representations of an empty type" do # An empty map component that survives syntactically (open_map(c: none()) # is a non-normalized empty, equal to none()) must report :badmap like # none(), not {:ok, }. From ac5f963fd66b48b1cf2874ada7ecceefa16bb803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 25 Jul 2026 18:03:40 +0200 Subject: [PATCH 3/3] Apply suggestion from @josevalim --- lib/elixir/test/elixir/module/types/descr_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir/test/elixir/module/types/descr_test.exs b/lib/elixir/test/elixir/module/types/descr_test.exs index 5f3ca3e7da..155810bbaa 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -3339,7 +3339,7 @@ defmodule Module.Types.DescrTest do # An empty map component that survives syntactically (open_map(c: none()) # is a non-normalized empty, equal to none()) must report :badmap like # none(), not {:ok, }. - a2 = open_map(c: none()) + a2 = open_map(c: {none(), false}) assert equal?(none(), a2) assert map_put(none(), atom([:a]), integer()) == :badmap assert map_put(a2, atom([:a]), integer()) == :badmap