Skip to content

Commit 2dc6773

Browse files
committed
Fix recursion on guards with map fields, closes #11602
1 parent ff103b1 commit 2dc6773

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

lib/elixir/lib/module/types/pattern.ex

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -403,10 +403,8 @@ defmodule Module.Types.Pattern do
403403
# bar, {:ok, baz}
404404
# bar, {:ok, bat}
405405

406-
expanded_args =
407-
args
408-
|> Enum.map(&flatten_union(&1, context))
409-
|> cartesian_product()
406+
flatten_args = Enum.map(args, &flatten_union(&1, context))
407+
cartesian_args = cartesian_product(flatten_args)
410408

411409
# Remove clauses that do not match the expected type
412410
# Ignore type variables in parameters by changing them to dynamic
@@ -425,11 +423,11 @@ defmodule Module.Types.Pattern do
425423
# the type contexts from unifying argument and parameter to
426424
# infer type variables in arguments
427425
result =
428-
flat_map_ok(expanded_args, fn expanded_args ->
426+
flat_map_ok(cartesian_args, fn cartesian_args ->
429427
result =
430428
Enum.flat_map(clauses, fn {params, return} ->
431429
result =
432-
map_ok(Enum.zip(expanded_args, params), fn {arg, param} ->
430+
map_ok(Enum.zip(cartesian_args, params), fn {arg, param} ->
433431
case unify(arg, param, stack, context) do
434432
{:ok, _type, context} -> {:ok, context}
435433
{:error, reason} -> {:error, reason}
@@ -453,7 +451,13 @@ defmodule Module.Types.Pattern do
453451
{:ok, returns_contexts} ->
454452
{success_returns, contexts} = Enum.unzip(returns_contexts)
455453
contexts = Enum.concat(contexts)
456-
indexes = Enum.uniq(Enum.flat_map(args, &collect_var_indexes_from_type/1))
454+
455+
indexes =
456+
for types <- flatten_args,
457+
type <- types,
458+
index <- collect_var_indexes_from_type(type),
459+
do: index,
460+
uniq: true
457461

458462
# Build unions from collected type contexts to unify with
459463
# type variables from arguments

lib/elixir/test/elixir/module/types/types_test.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,5 +687,18 @@ defmodule Module.Types.TypesTest do
687687
end
688688
) == :none
689689
end
690+
691+
test "no-recursion on guards with map fields" do
692+
assert warning(
693+
[assigns],
694+
(
695+
variable_enum = assigns.variable_enum
696+
697+
case true do
698+
_ when variable_enum != nil -> assigns.variable_enum
699+
end
700+
)
701+
) == :none
702+
end
690703
end
691704
end

0 commit comments

Comments
 (0)