Skip to content

Commit 0a77a35

Browse files
authored
More type checking of function applications (#14508)
1 parent fb19dec commit 0a77a35

File tree

4 files changed

+362
-302
lines changed

4 files changed

+362
-302
lines changed

lib/elixir/lib/module/types/apply.ex

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -472,19 +472,27 @@ defmodule Module.Types.Apply do
472472
Returns the type of a remote capture.
473473
"""
474474
def remote_capture(modules, fun, arity, meta, stack, context) do
475-
# TODO: We cannot return the unions of functions. Do we forbid this?
476-
# Do we check it is always the same return type? Do we simply say it is a function?
477-
if stack.mode == :traversal do
475+
# TODO: Do we check when the union of functions is invalid?
476+
# TODO: Deal with :infer types
477+
if stack.mode == :traversal or modules == [] do
478478
{dynamic(fun(arity)), context}
479479
else
480-
context =
481-
Enum.reduce(
482-
modules,
483-
context,
484-
&(signature(&1, fun, arity, meta, stack, &2) |> elem(1))
485-
)
480+
{type, fallback?, context} =
481+
Enum.reduce(modules, {none(), false, context}, fn module, {type, fallback?, context} ->
482+
case signature(module, fun, arity, meta, stack, context) do
483+
{{:strong, _, clauses}, context} ->
484+
{union(type, fun_from_non_overlapping_clauses(clauses)), fallback?, context}
485+
486+
{_, context} ->
487+
{type, true, context}
488+
end
489+
end)
486490

487-
{dynamic(fun(arity)), context}
491+
if fallback? do
492+
{dynamic(fun(arity)), context}
493+
else
494+
{type, context}
495+
end
488496
end
489497
end
490498

@@ -496,10 +504,10 @@ defmodule Module.Types.Apply do
496504
497505
* `:none` - no typing information found.
498506
499-
* `{:infer, domain or nil, clauses}` - clauses from inferences. You must check all
500-
all clauses and return the union between them. They are dynamic
501-
and they can only be converted into arrows by computing the union
502-
of all arguments.
507+
* `{:infer, domain or nil, clauses}` - clauses from inferences.
508+
You must check all clauses and return the union between them.
509+
They are dynamic and they can only be converted into arrows by
510+
computing the union of all arguments.
503511
504512
* `{:strong, domain or nil, clauses}` - clauses from signatures. So far
505513
these are strong arrows with non-overlapping domains

0 commit comments

Comments
 (0)