From 36c49eb5dabb29b70085135ceb33f00f17e2708c Mon Sep 17 00:00:00 2001 From: preciz Date: Sat, 25 Jul 2026 14:08:48 +0200 Subject: [PATCH 1/3] Defer function application computations until needed Assisted-by: Codex:GPT-5 --- lib/elixir/lib/module/types/descr.ex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index e975e7f893c..76c53f6a15e 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -1434,13 +1434,14 @@ defmodule Module.Types.Descr do # applying dynamic arrows to upper-bounded arguments in dynamic(). # - Mixed: union the static result with the dynamic-wrapped dynamic result. defp fun_apply_with_strategy(fun_static, fun_dynamic, arguments) do - args_domain = args_to_domain(arguments) - static? = fun_dynamic == nil and Enum.all?(arguments, fn arg -> not gradual?(arg) end) arity = length(arguments) if Enum.any?(arguments, &empty?/1) do {:badarg, arguments, true} else + args_domain = args_to_domain(arguments) + static? = fun_dynamic == nil and Enum.all?(arguments, fn arg -> not gradual?(arg) end) + with {:ok, domain, static_arrows, dynamic_arrows} <- fun_normalize_both(fun_static, fun_dynamic, arity) do cond do From d7f399df4e395071c24281110b8d2099dce73e78 Mon Sep 17 00:00:00 2001 From: preciz Date: Sat, 25 Jul 2026 15:19:14 +0200 Subject: [PATCH 2/3] Defer function application setup until normalization Assisted-by: Codex:GPT-5 --- lib/elixir/lib/module/types/descr.ex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index 76c53f6a15e..64cd017ff7e 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -1434,16 +1434,16 @@ defmodule Module.Types.Descr do # applying dynamic arrows to upper-bounded arguments in dynamic(). # - Mixed: union the static result with the dynamic-wrapped dynamic result. defp fun_apply_with_strategy(fun_static, fun_dynamic, arguments) do - arity = length(arguments) - if Enum.any?(arguments, &empty?/1) do {:badarg, arguments, true} else - args_domain = args_to_domain(arguments) - static? = fun_dynamic == nil and Enum.all?(arguments, fn arg -> not gradual?(arg) end) + arity = length(arguments) with {:ok, domain, static_arrows, dynamic_arrows} <- - fun_normalize_both(fun_static, fun_dynamic, arity) do + fun_normalize_both(fun_static, fun_dynamic, arity), + args_domain = args_to_domain(arguments), + static? = + fun_dynamic == nil and Enum.all?(arguments, fn arg -> not gradual?(arg) end) do cond do # The domain here is the extended gradual domain computed by # fun_normalize_both/3. If the argument does not satisfy it, we From 1683c256a92be0d1277dd27ed971d06cb09f194a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 25 Jul 2026 17:56:11 +0200 Subject: [PATCH 3/3] Refactor normalization logic in descr.ex --- lib/elixir/lib/module/types/descr.ex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index 64cd017ff7e..2cd7dc4c523 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -1440,10 +1440,10 @@ defmodule Module.Types.Descr do arity = length(arguments) with {:ok, domain, static_arrows, dynamic_arrows} <- - fun_normalize_both(fun_static, fun_dynamic, arity), - args_domain = args_to_domain(arguments), - static? = - fun_dynamic == nil and Enum.all?(arguments, fn arg -> not gradual?(arg) end) do + fun_normalize_both(fun_static, fun_dynamic, arity) do + args_domain = args_to_domain(arguments) + static? = fun_dynamic == nil and Enum.all?(arguments, fn arg -> not gradual?(arg) end) + cond do # The domain here is the extended gradual domain computed by # fun_normalize_both/3. If the argument does not satisfy it, we