Skip to content

Commit e648389

Browse files
committed
Tackle more TODOs
1 parent 79cfdc9 commit e648389

File tree

2 files changed

+31
-16
lines changed

2 files changed

+31
-16
lines changed

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

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ defmodule Module.Types.Expr do
115115
end
116116

117117
# <<...>>>
118-
# TODO: here (including tests)
119118
def of_expr({:<<>>, _meta, args}, _expected, _expr, stack, context) do
120119
context = Of.binary(args, :expr, stack, context)
121120
{binary(), context}
@@ -306,7 +305,6 @@ defmodule Module.Types.Expr do
306305
end
307306

308307
# TODO: fn pat -> expr end
309-
# TODO: here
310308
def of_expr({:fn, _meta, clauses}, _expected, _expr, stack, context) do
311309
[{:->, _, [head, _]} | _] = clauses
312310
{patterns, _guards} = extract_head(head)
@@ -399,8 +397,6 @@ defmodule Module.Types.Expr do
399397
|> dynamic_unless_static(stack)
400398
end
401399

402-
# TODO: for pat <- expr do expr end
403-
# TODO: here
404400
def of_expr({:for, meta, [_ | _] = args}, expected, expr, stack, context) do
405401
{clauses, [[{:do, block} | opts]]} = Enum.split(args, -1)
406402
context = Enum.reduce(clauses, context, &for_clause(&1, stack, &2))
@@ -414,6 +410,7 @@ defmodule Module.Types.Expr do
414410
# because this is recursive. We need to infer the block type first.
415411
of_clauses(block, [dynamic()], expected, expr, :for_reduce, stack, {reduce_type, context})
416412
else
413+
# TODO: Use the collectable protocol for the output
417414
into = Keyword.get(opts, :into, [])
418415
{into_wrapper, gradual?, context} = for_into(into, meta, stack, context)
419416
{block_type, context} = of_expr(block, @pending, block, stack, context)
@@ -469,7 +466,6 @@ defmodule Module.Types.Expr do
469466
end
470467
end
471468

472-
# TODO: here
473469
def of_expr(
474470
{{:., _, [remote, :apply]}, _meta, [mod, fun, args]} = call,
475471
expected,
@@ -505,7 +501,6 @@ defmodule Module.Types.Expr do
505501
end
506502
end
507503

508-
# TODO: here
509504
def of_expr({{:., _, [remote, name]}, meta, args} = call, expected, _expr, stack, context) do
510505
{remote_type, context} = of_expr(remote, atom(), call, stack, context)
511506
{mods, context} = Of.modules(remote_type, name, length(args), call, meta, stack, context)
@@ -532,21 +527,18 @@ defmodule Module.Types.Expr do
532527
end
533528

534529
# Super
535-
# TODO: here
536-
def of_expr({:super, meta, args} = expr, _expected, _expr, stack, context) when is_list(args) do
530+
def of_expr({:super, meta, args} = call, expected, _expr, stack, context) when is_list(args) do
537531
{_kind, fun} = Keyword.fetch!(meta, :super)
538-
apply_local(fun, args, expr, stack, context)
532+
apply_local(fun, args, expected, call, stack, context)
539533
end
540534

541535
# Local calls
542-
# TODO: here
543-
def of_expr({fun, _meta, args} = expr, _expected, _expr, stack, context)
536+
def of_expr({fun, _meta, args} = call, expected, _expr, stack, context)
544537
when is_atom(fun) and is_list(args) do
545-
apply_local(fun, args, expr, stack, context)
538+
apply_local(fun, args, expected, call, stack, context)
546539
end
547540

548541
# var
549-
# TODO: here
550542
def of_expr(var, expected, expr, stack, context) when is_var(var) do
551543
if stack.mode == :traversal do
552544
{dynamic(), context}
@@ -631,7 +623,6 @@ defmodule Module.Types.Expr do
631623
defp for_into(binary, _meta, _stack, context) when is_binary(binary),
632624
do: {[:binary], false, context}
633625

634-
# TODO: Use the collectable protocol for the output
635626
defp for_into(into, meta, stack, context) do
636627
meta =
637628
case into do
@@ -689,7 +680,7 @@ defmodule Module.Types.Expr do
689680

690681
## General helpers
691682

692-
defp apply_local(fun, args, {_, meta, _} = expr, stack, context) do
683+
defp apply_local(fun, args, _expected, {_, meta, _} = expr, stack, context) do
693684
{local_info, domain, context} = Apply.local_domain(fun, args, meta, stack, context)
694685

695686
{args_types, context} =

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,16 @@ defmodule Module.Types.ExprTest do
340340
end
341341

342342
describe "binaries" do
343+
test "inference" do
344+
assert typecheck!(
345+
[x, y],
346+
(
347+
<<x::float-size(y)>>
348+
{x, y}
349+
)
350+
) == dynamic(tuple([union(float(), integer()), integer()]))
351+
end
352+
343353
test "warnings" do
344354
assert typeerror!([<<x::binary-size(2)>>], <<x::float>>) ==
345355
~l"""
@@ -1606,7 +1616,7 @@ defmodule Module.Types.ExprTest do
16061616
) == dynamic(union(binary(), list(float())))
16071617
end
16081618

1609-
test ":reduce" do
1619+
test ":reduce checks" do
16101620
assert typecheck!(
16111621
[list],
16121622
for _ <- list, reduce: :ok do
@@ -1615,6 +1625,20 @@ defmodule Module.Types.ExprTest do
16151625
end
16161626
) == union(atom([:ok]), union(integer(), float()))
16171627
end
1628+
1629+
test ":reduce inference" do
1630+
assert typecheck!(
1631+
[list, x],
1632+
(
1633+
123 =
1634+
for _ <- list, reduce: x do
1635+
x -> x
1636+
end
1637+
1638+
x
1639+
)
1640+
) == dynamic(integer())
1641+
end
16181642
end
16191643

16201644
describe "apply" do

0 commit comments

Comments
 (0)