@@ -30,6 +30,8 @@ defmodule Module.Types.Expr do
3030 versioned_vars: open_map ( )
3131 )
3232
33+ # This is used temporarily until reverse arrows are defined
34+ @ pending term ( )
3335 @ atom_true atom ( [ true ] )
3436 @ exception open_map ( __struct__: atom ( ) , __exception__: @ atom_true )
3537
@@ -49,9 +51,6 @@ defmodule Module.Types.Expr do
4951 )
5052 )
5153
52- @ term term ( )
53- @ pending term ( )
54-
5554 # :atom
5655 def of_expr ( atom , _expected , _expr , _stack , context ) when is_atom ( atom ) ,
5756 do: { atom ( [ atom ] ) , context }
@@ -246,7 +245,7 @@ defmodule Module.Types.Expr do
246245
247246 context =
248247 Enum . reduce ( pre , context , fn expr , context ->
249- { _ , context } = of_expr ( expr , @ term , expr , stack , context )
248+ { _ , context } = of_expr ( expr , term ( ) , expr , stack , context )
250249 context
251250 end )
252251
@@ -367,7 +366,7 @@ defmodule Module.Types.Expr do
367366 |> dynamic_unless_static ( stack )
368367
369368 if after_block do
370- { _type , context } = of_expr ( after_block , @ term , after_block , stack , context )
369+ { _type , context } = of_expr ( after_block , term ( ) , after_block , stack , context )
371370 { type , context }
372371 else
373372 { type , context }
@@ -499,9 +498,10 @@ defmodule Module.Types.Expr do
499498 { Enum . reduce ( types , & union / 2 ) , context }
500499
501500 _ ->
502- # PENDING: Do not process args twice
503- apply_args = [ mod , fun , args ]
504- apply_one ( :erlang , :apply , apply_args , expected , call , stack , context )
501+ info = Apply . signature ( :erlang , :apply , 3 )
502+ { args_type , context } = of_expr ( args , list ( term ( ) ) , call , stack , context )
503+ apply_types = [ mod_type , fun_type , args_type ]
504+ Apply . remote_apply ( info , :erlang , :apply , apply_types , call , stack , context )
505505 end
506506 end
507507
@@ -600,7 +600,6 @@ defmodule Module.Types.Expr do
600600 expr = { :<- , [ type_check: :generator ] ++ meta , [ left , right ] }
601601 { pattern , guards } = extract_head ( [ left ] )
602602
603- # PENDING: test this
604603 { _type , context } =
605604 apply_one ( Enumerable , :count , [ right ] , dynamic ( ) , expr , stack , context )
606605
@@ -620,7 +619,7 @@ defmodule Module.Types.Expr do
620619 end
621620
622621 defp for_clause ( expr , stack , context ) do
623- { _type , context } = of_expr ( expr , @ term , expr , stack , context )
622+ { _type , context } = of_expr ( expr , term ( ) , expr , stack , context )
624623 context
625624 end
626625
@@ -634,7 +633,18 @@ defmodule Module.Types.Expr do
634633
635634 # TODO: Use the collectable protocol for the output
636635 defp for_into ( into , meta , stack , context ) do
637- { type , context } = of_expr ( into , @ pending , into , stack , context )
636+ meta =
637+ case into do
638+ { _ , meta , _ } -> meta
639+ _ -> meta
640+ end
641+
642+ expr = { :__block__ , [ type_check: :into ] ++ meta , [ into ] }
643+
644+ { info , [ domain ] , context } =
645+ Apply . remote_domain ( Collectable , :into , [ into ] , term ( ) , meta , stack , context )
646+
647+ { type , context } = of_expr ( into , domain , expr , stack , context )
638648
639649 # We use subtype? instead of compatible because we want to handle
640650 # only binary/list, even if a dynamic with something else is given.
@@ -645,17 +655,8 @@ defmodule Module.Types.Expr do
645655 { _ , _ } -> { [ :binary , :list ] , gradual? ( type ) , context }
646656 end
647657 else
648- meta =
649- case into do
650- { _ , meta , _ } -> meta
651- _ -> meta
652- end
653-
654- # PENDING: do not do this twice
655- expr = { :__block__ , [ type_check: :into ] ++ meta , [ into ] }
656-
657658 { _type , context } =
658- apply_one ( Collectable , :into , [ into ] , dynamic ( ) , expr , stack , context )
659+ Apply . remote_apply ( info , Collectable , :into , [ type ] , expr , stack , context )
659660
660661 { [ :term ] , true , context }
661662 end
0 commit comments