From e229fca20ceaadae8fc1ec630bd6058f228e3073 Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Sun, 21 Jun 2026 19:20:13 +0200 Subject: [PATCH] Return error from `compatible_intersection` with none Match fast path behaviour with `compatible?/2` Fixes #15511 --- lib/elixir/lib/module/types/descr.ex | 8 +++++++- lib/elixir/test/elixir/module/types/descr_test.exs | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index 620c03e956f..7dd4169f241 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -950,7 +950,13 @@ defmodule Module.Types.Descr do domain of a function. It is used to refine dynamic types as we traverse the program. """ - def compatible_intersection(other, :term), do: {:ok, remove_optional(other)} + def compatible_intersection(other, :term) do + if empty?(other) do + {:error, other} + else + {:ok, remove_optional(other)} + end + end def compatible_intersection(left, right) do {left_dynamic, left_static} = pop_dynamic(left) diff --git a/lib/elixir/test/elixir/module/types/descr_test.exs b/lib/elixir/test/elixir/module/types/descr_test.exs index 198b0c6d69a..ef5346b9024 100644 --- a/lib/elixir/test/elixir/module/types/descr_test.exs +++ b/lib/elixir/test/elixir/module/types/descr_test.exs @@ -1180,6 +1180,17 @@ defmodule Module.Types.DescrTest do assert compatible?(dynamic(list(term())), list(integer())) assert compatible?(dynamic(list(term(), term())), list(integer(), integer())) end + + test "compatible_intersection agrees with compatible? on empty inputs" do + refute compatible?(none(), term()) + assert compatible_intersection(none(), term()) == {:error, none()} + + refute compatible?(dynamic(none()), term()) + assert compatible_intersection(dynamic(none()), term()) == {:error, dynamic(none())} + + assert compatible_intersection(integer(), term()) == {:ok, integer()} + assert compatible_intersection(dynamic(integer()), term()) == {:ok, dynamic(integer())} + end end describe "empty?" do