Skip to content

Commit 4dd0d5d

Browse files
committed
Spread pattern info namespace over positive and negative keys
1 parent dfa7333 commit 4dd0d5d

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

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

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ defmodule Module.Types.Pattern do
4242
end
4343

4444
defp of_pattern_args(patterns, expected_types, stack, context) do
45-
context = %{context | pattern_info: {%{}, %{}, 0}}
45+
context = init_pattern_info(context)
4646
{trees, context} = of_pattern_args_index(patterns, expected_types, 0, [], stack, context)
4747

4848
{types, context} =
@@ -104,7 +104,7 @@ defmodule Module.Types.Pattern do
104104
the given expected and expr or an error in case of a typing conflict.
105105
"""
106106
def of_match(pattern, expected, expr, stack, context) do
107-
context = %{context | pattern_info: {%{}, %{}, 0}}
107+
context = init_pattern_info(context)
108108
{tree, context} = of_pattern(pattern, [{:arg, 0, expected, expr}], stack, context)
109109

110110
{[type], context} =
@@ -119,7 +119,7 @@ defmodule Module.Types.Pattern do
119119

120120
defp of_pattern_recur(types, stack, context, callback) do
121121
%{pattern_info: {pattern_vars, pattern_info, _counter}} = context
122-
context = %{context | pattern_info: nil}
122+
context = nilify_pattern_info(context)
123123
pattern_vars = Map.to_list(pattern_vars)
124124
changed = :lists.seq(0, length(types) - 1)
125125

@@ -174,11 +174,9 @@ defmodule Module.Types.Pattern do
174174
case paths do
175175
# A single change, check if there are other variables in this index.
176176
[[_var, {:arg, index, _, _} | _]] ->
177-
arg_cons = [:arg | index]
178-
179177
case info do
180-
%{^arg_cons => true} -> {[index | changed], context}
181-
%{^arg_cons => false} -> {changed, context}
178+
%{^index => true} -> {[index | changed], context}
179+
%{^index => false} -> {changed, context}
182180
end
183181

184182
# Several changes, we have to recompute all indexes.
@@ -254,7 +252,7 @@ defmodule Module.Types.Pattern do
254252
defp of_pattern_var([{:head, counter} | rest], type, info, context) do
255253
case list_hd(type) do
256254
{_, head} ->
257-
tree = Map.fetch!(info, [:head | counter])
255+
tree = Map.fetch!(info, -counter)
258256
type = intersection(of_pattern_tree(tree, context), head)
259257
of_pattern_var(rest, type, info, context)
260258

@@ -484,14 +482,13 @@ defmodule Module.Types.Pattern do
484482

485483
paths = [[var | path] | Map.get(vars, version, [])]
486484
vars = Map.put(vars, version, paths)
487-
arg_cons = [:arg | arg]
488485

489486
# Our goal here is to compute if an argument has more than one variable.
490487
info =
491488
case info do
492-
%{^arg_cons => false} -> %{info | arg_cons => true}
493-
%{^arg_cons => true} -> info
494-
%{} -> Map.put(info, arg_cons, false)
489+
%{^arg => false} -> %{info | arg => true}
490+
%{^arg => true} -> info
491+
%{} -> Map.put(info, arg, false)
495492
end
496493

497494
{{:var, version}, %{context | pattern_info: {vars, info, counter}}}
@@ -562,7 +559,7 @@ defmodule Module.Types.Pattern do
562559
arg, {static, dynamic, info, context} ->
563560
counter = map_size(info) + counter
564561
{type, context} = of_pattern(arg, [{:head, counter} | path], stack, context)
565-
info = Map.put(info, [:head | counter], type)
562+
info = Map.put(info, -counter, type)
566563

567564
if is_descr(type) do
568565
{[type | static], dynamic, info, context}
@@ -713,6 +710,18 @@ defmodule Module.Types.Pattern do
713710

714711
## Helpers
715712

713+
# pattern_info stores the variables defined in patterns,
714+
# additional information about the number of variables in
715+
# arguments and list heads, and a counter used to compute
716+
# the number of list heads.
717+
defp init_pattern_info(context) do
718+
%{context | pattern_info: {%{}, %{}, 1}}
719+
end
720+
721+
defp nilify_pattern_info(context) do
722+
%{context | pattern_info: nil}
723+
end
724+
716725
def format_diagnostic({:invalid_pattern, expr, context}) do
717726
traces = collect_traces(expr, context)
718727

0 commit comments

Comments
 (0)