Skip to content

Commit 0fe5b13

Browse files
committed
Perform reverse arrows on with even when not precise
1 parent 808075d commit 0fe5b13

3 files changed

Lines changed: 23 additions & 10 deletions

File tree

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -768,17 +768,13 @@ defmodule Module.Types.Expr do
768768
{trees, precise?, context} =
769769
Pattern.of_generator(pattern, guards, type, :with, expr, meta, stack, context)
770770

771-
if precise? do
772-
[pattern_type] = Pattern.of_domain(trees, stack, context)
771+
[pattern_type] = Pattern.of_domain(trees, stack, context)
773772

774-
{_, refined_context} =
775-
of_expr(right, pattern_type, right, %{stack | reverse_arrow: :use}, context)
773+
{_, refined_context} =
774+
of_expr(right, pattern_type, right, %{stack | reverse_arrow: :use}, context)
776775

777-
{union(difference(type, pattern_type), else_types),
778-
reset_warnings(refined_context, context)}
779-
else
780-
{union(type, else_types), context}
781-
end
776+
else_type = if precise?, do: difference(type, pattern_type), else: type
777+
{union(else_type, else_types), reset_warnings(refined_context, context)}
782778
end
783779

784780
defp with_clause(expr, stack, {else_types, context}) do

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ defmodule Module.Types.Pattern do
342342
of_pattern_refine(types, changed, pattern_info, tag, stack, context) do
343343
{args, pattern_precise? and guard_precise?, context}
344344
else
345-
{:error, context} -> {tree, false, context}
345+
{:error, context} -> {args, false, context}
346346
end
347347
end
348348

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,6 +2711,23 @@ defmodule Module.Types.ExprTest do
27112711
) ==
27122712
dynamic(union(binary(), atom([nil, :not_precise])))
27132713
|> union(atom([:not_precise]))
2714+
2715+
assert typecheck!(
2716+
[x],
2717+
with :ok <- System.get_env(x) && :ok do
2718+
{:ok, x}
2719+
end
2720+
) ==
2721+
dynamic(union(tuple([atom([:ok]), binary()]), atom([nil])))
2722+
2723+
assert typecheck!(
2724+
[x],
2725+
with {:ok, "not precise"} <- if(y = System.get_env(x), do: {:ok, y}) do
2726+
{:ok, x}
2727+
end
2728+
) ==
2729+
dynamic(union(tuple([atom([:ok]), binary()]), atom([nil])))
2730+
|> union(atom([nil]))
27142731
end
27152732

27162733
test "warns on non-matching generators" do

0 commit comments

Comments
 (0)