Skip to content

Commit d6bd53d

Browse files
committed
No more root
1 parent 9cbab98 commit d6bd53d

1 file changed

Lines changed: 32 additions & 55 deletions

File tree

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

Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -433,12 +433,12 @@ defmodule Module.Types.Pattern do
433433
"""
434434
def of_size(:match, arg, expr, stack, %{pattern_info: pattern_info} = context) do
435435
context = init_guard_info(context)
436-
{type, context} = of_guard(arg, {false, integer()}, expr, stack, context)
436+
{type, context} = of_guard(arg, integer(), expr, stack, context)
437437
{type, %{context | pattern_info: pattern_info}}
438438
end
439439

440440
def of_size(:guard, arg, expr, stack, context) do
441-
of_guard(arg, {false, integer()}, expr, stack, context)
441+
of_guard(arg, integer(), expr, stack, context)
442442
end
443443

444444
## Patterns
@@ -771,7 +771,7 @@ defmodule Module.Types.Pattern do
771771

772772
context =
773773
Enum.reduce(guards, context, fn guard, context ->
774-
{type, context} = of_guard(guard, {true, @atom_true}, guard, stack, context)
774+
{type, context} = of_guard(guard, @atom_true, guard, stack, context)
775775

776776
if never_true?(type) do
777777
error = {:badguard, type, guard, context}
@@ -794,148 +794,125 @@ defmodule Module.Types.Pattern do
794794
end
795795

796796
# :atom
797-
def of_guard(atom, _root_expected, _expr, _stack, context) when is_atom(atom) do
797+
def of_guard(atom, _expected, _expr, _stack, context) when is_atom(atom) do
798798
{atom([atom]), context}
799799
end
800800

801801
# 12
802-
def of_guard(literal, _root_expected, _expr, _stack, context) when is_integer(literal) do
802+
def of_guard(literal, _expected, _expr, _stack, context) when is_integer(literal) do
803803
{integer(), context}
804804
end
805805

806806
# 1.2
807-
def of_guard(literal, _root_expected, _expr, _stack, context) when is_float(literal) do
807+
def of_guard(literal, _expected, _expr, _stack, context) when is_float(literal) do
808808
{float(), context}
809809
end
810810

811811
# "..."
812-
def of_guard(literal, _root_expected, _expr, _stack, context) when is_binary(literal) do
812+
def of_guard(literal, _expected, _expr, _stack, context) when is_binary(literal) do
813813
{binary(), context}
814814
end
815815

816816
# []
817-
def of_guard([], _root_expected, _expr, _stack, context) do
817+
def of_guard([], _expected, _expr, _stack, context) do
818818
{empty_list(), context}
819819
end
820820

821821
# [expr, ...]
822-
def of_guard(list, _root_expected, expr, stack, context) when is_list(list) do
822+
def of_guard(list, _expected, expr, stack, context) when is_list(list) do
823823
{prefix, suffix} = unpack_list(list, [])
824824

825825
{prefix, context} =
826-
Enum.map_reduce(prefix, context, &of_guard(&1, {false, term()}, expr, stack, &2))
826+
Enum.map_reduce(prefix, context, &of_guard(&1, term(), expr, stack, &2))
827827

828-
{suffix, context} = of_guard(suffix, {false, term()}, expr, stack, context)
828+
{suffix, context} = of_guard(suffix, term(), expr, stack, context)
829829
{non_empty_list(Enum.reduce(prefix, &union/2), suffix), context}
830830
end
831831

832832
# {left, right}
833-
def of_guard({left, right}, root_expected, expr, stack, context) do
834-
of_guard({:{}, [], [left, right]}, root_expected, expr, stack, context)
833+
def of_guard({left, right}, expected, expr, stack, context) do
834+
of_guard({:{}, [], [left, right]}, expected, expr, stack, context)
835835
end
836836

837837
# %Struct{...}
838-
def of_guard(
839-
{:%, meta, [module, {:%{}, _, args}]} = struct,
840-
{_root, expected},
841-
_expr,
842-
stack,
843-
context
844-
)
838+
def of_guard({:%, meta, [module, {:%{}, _, args}]} = struct, expected, _expr, stack, context)
845839
when is_atom(module) do
846-
fun = &of_guard(&1, {false, &2}, struct, &3, &4)
840+
fun = &of_guard(&1, &2, struct, &3, &4)
847841
Of.struct_instance(module, args, expected, meta, stack, context, fun)
848842
end
849843

850844
# %{...}
851-
def of_guard({:%{}, _meta, args}, {_root, expected}, expr, stack, context) do
852-
Of.closed_map(args, expected, stack, context, &of_guard(&1, {false, &2}, expr, &3, &4))
845+
def of_guard({:%{}, _meta, args}, expected, expr, stack, context) do
846+
Of.closed_map(args, expected, stack, context, &of_guard(&1, &2, expr, &3, &4))
853847
end
854848

855849
# <<>>
856-
def of_guard({:<<>>, _meta, args}, _root_expected, _expr, stack, context) do
850+
def of_guard({:<<>>, _meta, args}, _expected, _expr, stack, context) do
857851
context = Of.binary(args, :guard, stack, context)
858852
{binary(), context}
859853
end
860854

861855
# ^var
862-
def of_guard({:^, _meta, [var]}, {_root, expected}, expr, stack, context) do
856+
def of_guard({:^, _meta, [var]}, expected, expr, stack, context) do
863857
# This is used by binary size, which behaves as a mixture of match and guard
864858
Of.refine_body_var(var, expected, expr, stack, context)
865859
end
866860

867861
# {...}
868-
def of_guard({:{}, _meta, args}, _root_expected, expr, stack, context) do
869-
{types, context} =
870-
Enum.map_reduce(args, context, &of_guard(&1, {false, term()}, expr, stack, &2))
871-
862+
def of_guard({:{}, _meta, args}, _expected, expr, stack, context) do
863+
{types, context} = Enum.map_reduce(args, context, &of_guard(&1, term(), expr, stack, &2))
872864
{tuple(types), context}
873865
end
874866

875867
# var.field
876-
def of_guard(
877-
{{:., _, [callee, key]}, _, []} = map_fetch,
878-
{_root, expected},
879-
expr,
880-
stack,
881-
context
882-
)
868+
def of_guard({{:., _, [callee, key]}, _, []} = map_fetch, expected, expr, stack, context)
883869
when not is_atom(callee) do
884-
{type, context} = of_guard(callee, {false, open_map([{key, expected}])}, expr, stack, context)
870+
{type, context} = of_guard(callee, open_map([{key, expected}]), expr, stack, context)
885871
Of.map_fetch(map_fetch, type, key, stack, context)
886872
end
887873

888874
# Remote
889-
def of_guard({{:., _, [:erlang, fun]}, meta, args} = call, root_expected, _, stack, context)
875+
def of_guard({{:., _, [:erlang, fun]}, meta, args} = call, expected, _, stack, context)
890876
when is_atom(fun) do
891-
of_remote(fun, meta, args, call, root_expected, stack, context)
877+
of_remote(fun, meta, args, call, expected, stack, context)
892878
end
893879

894880
# var
895-
def of_guard(var, {_root, expected}, expr, stack, context) when is_var(var) do
881+
def of_guard(var, expected, expr, stack, context) when is_var(var) do
896882
case context.pattern_info do
897883
{true} -> Of.refine_body_var(var, expected, expr, stack, context)
898884
{false} -> {Of.var(var, context), context}
899885
end
900886
end
901887

902888
# TODO: Move orelse and andalso handling here, both may never be executed
903-
defp of_remote(fun, meta, [left, right], call, {_root, expected}, stack, context)
889+
defp of_remote(fun, meta, [left, right], call, expected, stack, context)
904890
when fun in [:or, :orelse] do
905891
{info, [left_domain, right_domain], context} =
906892
Apply.remote_domain(:erlang, fun, [left, right], expected, meta, stack, context)
907893

908-
{left_type, context} = of_guard(left, {false, left_domain}, call, stack, context)
894+
{left_type, context} = of_guard(left, left_domain, call, stack, context)
909895

910896
{right_type, context} =
911897
if fun == :or do
912-
of_guard(right, {false, right_domain}, call, stack, context)
898+
of_guard(right, right_domain, call, stack, context)
913899
else
914900
%{pattern_info: pattern_info} = context
915901
context = %{context | pattern_info: {false}}
916-
{type, context} = of_guard(right, {false, right_domain}, call, stack, context)
902+
{type, context} = of_guard(right, right_domain, call, stack, context)
917903
{type, %{context | pattern_info: pattern_info}}
918904
end
919905

920906
args_types = [left_type, right_type]
921907
Apply.remote_apply(info, :erlang, fun, args_types, call, stack, context)
922908
end
923909

924-
defp of_remote(fun, meta, args, call, {root, expected}, stack, context) do
925-
# If we are the root, we are only interested in positive results,
926-
# except for the operations that can return :fail.
927-
expected =
928-
if root and fun not in [:element, :hd, :map_get, :max, :min, :tl] do
929-
@atom_true
930-
else
931-
expected
932-
end
933-
910+
defp of_remote(fun, meta, args, call, expected, stack, context) do
934911
{info, domain, context} =
935912
Apply.remote_domain(:erlang, fun, args, expected, meta, stack, context)
936913

937914
{args_types, context} =
938-
zip_map_reduce(args, domain, context, &of_guard(&1, {false, &2}, call, stack, &3))
915+
zip_map_reduce(args, domain, context, &of_guard(&1, &2, call, stack, &3))
939916

940917
Apply.remote_apply(info, :erlang, fun, args_types, call, stack, context)
941918
end

0 commit comments

Comments
 (0)