From d147f2c4e2c2fce24f02b0ce746b77a041635aa1 Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Sun, 21 Jun 2026 20:01:00 +0200 Subject: [PATCH 1/3] Correctly render list with negative leaves BDD leaves represent non empty lists Fixes #15513 --- lib/elixir/lib/module/types/descr.ex | 2 +- lib/elixir/test/elixir/module/types/descr_test.exs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index 620c03e956f..6e527a83369 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -2505,7 +2505,7 @@ defmodule Module.Types.Descr do [to_quoted(ty, opts), to_quoted(lst, opts)] end - {name, [], args} + {:non_empty_list, [], args} end) |> Kernel.then( &[ diff --git a/lib/elixir/test/elixir/module/types/descr_test.exs b/lib/elixir/test/elixir/module/types/descr_test.exs index 198b0c6d69a..67ea8091370 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -3405,6 +3405,12 @@ defmodule Module.Types.DescrTest do assert list(term()) |> opt_difference(list(integer())) |> to_quoted_string() == "non_empty_list(term()) and not non_empty_list(integer())" + keeps_empty = opt_difference(list(term()), non_empty_list(integer())) + assert subtype?(empty_list(), keeps_empty) + + assert to_quoted_string(keeps_empty) == + "list(term()) and not non_empty_list(integer())" + assert list(term()) |> opt_difference(list(integer())) |> opt_difference(list(atom())) From 279f7da3b2ee5de3f78e277ccf7552f63696d9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 21 Jun 2026 21:32:36 +0200 Subject: [PATCH 2/3] Apply suggestion from @josevalim --- lib/elixir/test/elixir/module/types/descr_test.exs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/elixir/test/elixir/module/types/descr_test.exs b/lib/elixir/test/elixir/module/types/descr_test.exs index 67ea8091370..108f4ed2c17 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -3405,10 +3405,7 @@ defmodule Module.Types.DescrTest do assert list(term()) |> opt_difference(list(integer())) |> to_quoted_string() == "non_empty_list(term()) and not non_empty_list(integer())" - keeps_empty = opt_difference(list(term()), non_empty_list(integer())) - assert subtype?(empty_list(), keeps_empty) - - assert to_quoted_string(keeps_empty) == + assert to_quoted_string(opt_difference(list(term()), non_empty_list(integer()))) == "list(term()) and not non_empty_list(integer())" assert list(term()) From a71e6f0419180c599c632b108908afbcf62d3b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 21 Jun 2026 21:33:14 +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 108f4ed2c17..2c701f7103a 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -3405,7 +3405,7 @@ defmodule Module.Types.DescrTest do assert list(term()) |> opt_difference(list(integer())) |> to_quoted_string() == "non_empty_list(term()) and not non_empty_list(integer())" - assert to_quoted_string(opt_difference(list(term()), non_empty_list(integer()))) == + assert opt_difference(list(term()), non_empty_list(integer())) |> to_quoted_string() == "list(term()) and not non_empty_list(integer())" assert list(term())