Skip to content

Commit

Permalink
Pass args as explicit argument to Apply.remote
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Dec 28, 2024
1 parent 4f0b0d9 commit 4787116
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 37 deletions.
44 changes: 15 additions & 29 deletions lib/elixir/lib/module/types/apply.ex
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,11 @@ defmodule Module.Types.Apply do
@doc """
Applies a function in a given module.
"""
def remote(_module, _fun, _args_types, _expr, %{mode: :traversal}, context) do
def remote(_module, _fun, _args, _args_types, _expr, %{mode: :traversal}, context) do
{dynamic(), context}
end

def remote(:erlang, :element, [_, tuple], {_, meta, [index, _]} = expr, stack, context)
def remote(:erlang, :element, [index, _], [_, tuple], expr, stack, context)
when is_integer(index) do
case tuple_fetch(tuple, index - 1) do
{_optional?, value_type} ->
Expand All @@ -294,18 +294,11 @@ defmodule Module.Types.Apply do
mfac = mfac(expr, :erlang, :element, 2)

{error_type(),
error({:badindex, mfac, expr, tuple, index - 1, context}, meta, stack, context)}
error({:badindex, mfac, expr, tuple, index - 1, context}, elem(expr, 1), stack, context)}
end
end

def remote(
:erlang,
:insert_element,
[_, tuple, value],
{_, meta, [index, _, _]} = expr,
stack,
context
)
def remote(:erlang, :insert_element, [index, _, _], [_, tuple, value], expr, stack, context)
when is_integer(index) do
case tuple_insert_at(tuple, index - 1, value) do
value_type when is_descr(value_type) ->
Expand All @@ -321,11 +314,11 @@ defmodule Module.Types.Apply do
mfac = mfac(expr, :erlang, :insert_element, 3)

{error_type(),
error({:badindex, mfac, expr, tuple, index - 2, context}, meta, stack, context)}
error({:badindex, mfac, expr, tuple, index - 2, context}, elem(expr, 1), stack, context)}
end
end

def remote(:erlang, :delete_element, [_, tuple], {_, meta, [index, _]} = expr, stack, context)
def remote(:erlang, :delete_element, [index, _], [_, tuple], expr, stack, context)
when is_integer(index) do
case tuple_delete_at(tuple, index - 1) do
value_type when is_descr(value_type) ->
Expand All @@ -341,16 +334,16 @@ defmodule Module.Types.Apply do
mfac = mfac(expr, :erlang, :delete_element, 2)

{error_type(),
error({:badindex, mfac, expr, tuple, index - 1, context}, meta, stack, context)}
error({:badindex, mfac, expr, tuple, index - 1, context}, elem(expr, 1), stack, context)}
end
end

def remote(:erlang, :make_tuple, [_, elem], {_, _meta, [size, _]}, _stack, context)
def remote(:erlang, :make_tuple, [size, _], [_, elem], _expr, _stack, context)
when is_integer(size) and size >= 0 do
{tuple(List.duplicate(elem, size)), context}
end

def remote(:erlang, :hd, [list], expr, stack, context) do
def remote(:erlang, :hd, _args, [list], expr, stack, context) do
case list_hd(list) do
{_, value_type} ->
{value_type, context}
Expand All @@ -360,7 +353,7 @@ defmodule Module.Types.Apply do
end
end

def remote(:erlang, :tl, [list], expr, stack, context) do
def remote(:erlang, :tl, _args, [list], expr, stack, context) do
case list_tl(list) do
{_, value_type} ->
{value_type, context}
Expand All @@ -370,7 +363,7 @@ defmodule Module.Types.Apply do
end
end

def remote(:erlang, name, [left, right] = args_types, expr, stack, context)
def remote(:erlang, name, _args, [left, right], expr, stack, context)
when name in [:>=, :"=<", :>, :<, :min, :max] do
context =
cond do
Expand All @@ -396,18 +389,11 @@ defmodule Module.Types.Apply do
if name in [:min, :max] do
{union(left, right), context}
else
{return(boolean(), args_types, stack), context}
{return(boolean(), [left, right], stack), context}
end
end

def remote(
:erlang,
name,
[left, right] = args_types,
{_, _, args} = expr,
stack,
context
)
def remote(:erlang, name, args, [left, right] = args_types, expr, stack, context)
when name in [:==, :"/=", :"=:=", :"=/="] do
context =
cond do
Expand All @@ -429,13 +415,13 @@ defmodule Module.Types.Apply do
{return(boolean(), args_types, stack), context}
end

def remote(mod, fun, args_types, expr, stack, context) do
def remote(mod, fun, args, args_types, expr, stack, context) do
arity = length(args_types)

case :elixir_rewrite.inline(mod, fun, arity) do
{new_mod, new_fun} ->
expr = inline_meta(expr, mod, fun)
remote(new_mod, new_fun, args_types, expr, stack, context)
remote(new_mod, new_fun, args, args_types, expr, stack, context)

false ->
{info, context} = signature(mod, fun, arity, elem(expr, 1), stack, context)
Expand Down
14 changes: 7 additions & 7 deletions lib/elixir/lib/module/types/expr.ex
Original file line number Diff line number Diff line change
Expand Up @@ -383,15 +383,15 @@ defmodule Module.Types.Expr do
Of.map_fetch(expr, type, key_or_fun, stack, context)
else
{mods, context} = Of.modules(type, key_or_fun, 0, [:dot], expr, meta, stack, context)
apply_many(mods, key_or_fun, [], expr, stack, context)
apply_many(mods, key_or_fun, [], [], expr, stack, context)
end
end

def of_expr({{:., _, [remote, name]}, meta, args} = expr, stack, context) do
{remote_type, context} = of_expr(remote, stack, context)
{args_types, context} = Enum.map_reduce(args, context, &of_expr(&1, stack, &2))
{mods, context} = Of.modules(remote_type, name, length(args), expr, meta, stack, context)
apply_many(mods, name, args_types, expr, stack, context)
apply_many(mods, name, args, args_types, expr, stack, context)
end

# TODO: &Foo.bar/1
Expand Down Expand Up @@ -540,18 +540,18 @@ defmodule Module.Types.Expr do

## General helpers

defp apply_many([], function, args_types, expr, stack, context) do
defp apply_many([], function, _args, args_types, expr, stack, context) do
Apply.remote(function, args_types, expr, stack, context)
end

defp apply_many([mod], function, args_types, expr, stack, context) do
Apply.remote(mod, function, args_types, expr, stack, context)
defp apply_many([mod], function, args, args_types, expr, stack, context) do
Apply.remote(mod, function, args, args_types, expr, stack, context)
end

defp apply_many(mods, function, args_types, expr, stack, context) do
defp apply_many(mods, function, args, args_types, expr, stack, context) do
{returns, context} =
Enum.map_reduce(mods, context, fn mod, context ->
Apply.remote(mod, function, args_types, expr, stack, context)
Apply.remote(mod, function, args, args_types, expr, stack, context)
end)

{Enum.reduce(returns, &union/2), context}
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir/lib/module/types/pattern.ex
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ defmodule Module.Types.Pattern do
{args_type, context} =
Enum.map_reduce(args, context, &of_guard(&1, dynamic(), expr, stack, &2))

Module.Types.Apply.remote(:erlang, function, args_type, call, stack, context)
Module.Types.Apply.remote(:erlang, function, args, args_type, call, stack, context)
end

# var
Expand Down

0 comments on commit 4787116

Please sign in to comment.