Skip to content

Commit aa22242

Browse files
committed
Use conditional vars when applying across modules
1 parent caea8bc commit aa22242

File tree

3 files changed

+11
-20
lines changed

3 files changed

+11
-20
lines changed

lib/elixir/lib/module/types.ex

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,7 @@ defmodule Module.Types do
435435
# The mode to be used, see the @modes attribute
436436
mode: mode,
437437
# The function for handling local calls
438-
local_handler: handler,
439-
# Control if variable refinement is enabled.
440-
# It is disabled only on dynamic dispatches.
441-
refine_vars: true
438+
local_handler: handler
442439
}
443440
end
444441

lib/elixir/lib/module/types/expr.ex

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -502,10 +502,7 @@ defmodule Module.Types.Expr do
502502

503503
# var
504504
def of_expr(var, expected, expr, stack, context) when is_var(var) do
505-
case stack do
506-
%{refine_vars: false} -> {Of.var(var, context), context}
507-
%{} -> Of.refine_body_var(var, expected, expr, stack, context)
508-
end
505+
Of.refine_body_var(var, expected, expr, stack, context)
509506
end
510507

511508
## Tuples
@@ -691,14 +688,14 @@ defmodule Module.Types.Expr do
691688
apply_one(mod, fun, args, expected, expr, stack, context)
692689
end
693690

694-
defp apply_many(mods, fun, args, expected, {remote, meta, args}, stack, context) do
695-
{returns, context} =
696-
Enum.map_reduce(mods, context, fn mod, context ->
697-
expr = {remote, [type_check: {:invoked_as, mod, fun, length(args)}] ++ meta, args}
698-
apply_one(mod, fun, args, expected, expr, %{stack | refine_vars: false}, context)
699-
end)
691+
defp apply_many(mods, fun, args, expected, call, stack, context) do
692+
{remote, meta, _} = call
700693

701-
{Enum.reduce(returns, &union/2), context}
694+
Of.with_conditional_vars(mods, none(), call, stack, context, fn mod, acc, context ->
695+
expr = {remote, [type_check: {:invoked_as, mod, fun, length(args)}] ++ meta, args}
696+
{type, context} = apply_one(mod, fun, args, expected, expr, stack, context)
697+
{union(acc, type), context}
698+
end)
702699
end
703700

704701
defp reduce_non_empty([last], acc, fun),

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,18 +528,15 @@ defmodule Module.Types.ExprTest do
528528
"""
529529
end
530530

531-
test "requires all combinations to be compatible (except refinements)" do
531+
test "computes union of all combinations" do
532532
assert typecheck!(
533533
[condition, arg],
534534
(
535-
# While the code below may raise, it may also always succeed
536-
# if condition and arg are passed in tandem. Therefore, we
537-
# turn off refinement on dynamic calls.
538535
mod = if condition, do: String, else: List
539536
res = mod.to_integer(arg)
540537
{arg, res}
541538
)
542-
) == tuple([dynamic(), integer()])
539+
) == dynamic(tuple([union(binary(), non_empty_list(integer())), integer()]))
543540

544541
assert typeerror!(
545542
[condition],

0 commit comments

Comments
 (0)