@@ -321,15 +321,24 @@ defmodule Module.Types.Of do
321
321
322
322
for { mod , fun , clauses } <- [
323
323
{ :erlang , :binary_to_integer , [ { [ binary ( ) ] , integer ( ) } ] } ,
324
- { :erlang , :integer_to_binary , [ { [ integer ( ) ] , binary ( ) } ] }
324
+ { :erlang , :integer_to_binary , [ { [ integer ( ) ] , binary ( ) } ] } ,
325
+
326
+ # TODO: Replace term()/dynamic() by parametric types
327
+ { :erlang , :hd , [ { [ non_empty_list ( term ( ) , term ( ) ) ] , dynamic ( ) } ] } ,
328
+ { :erlang , :tl , [ { [ non_empty_list ( term ( ) , term ( ) ) ] , dynamic ( ) } ] } ,
329
+ { :erlang , :delete_element ,
330
+ [ { [ integer ( ) , open_tuple ( [ ] , term ( ) ) ] , dynamic ( open_tuple ( [ ] , term ( ) ) ) } ] } ,
331
+ { :erlang , :element , [ { [ integer ( ) , open_tuple ( [ ] , term ( ) ) ] , dynamic ( ) } ] } ,
332
+ { :erlang , :insert_element ,
333
+ [ { [ integer ( ) , open_tuple ( [ ] , term ( ) ) , term ( ) ] , dynamic ( open_tuple ( [ ] , term ( ) ) ) } ] }
325
334
] do
326
335
[ { args , _return } | _others ] = clauses
327
336
328
- defp strong_remote ( unquote ( mod ) , unquote ( fun ) , unquote ( length ( args ) ) ) ,
337
+ defp remote ( unquote ( mod ) , unquote ( fun ) , unquote ( length ( args ) ) ) ,
329
338
do: unquote ( Macro . escape ( clauses ) )
330
339
end
331
340
332
- defp strong_remote ( _mod , _fun , _arity ) , do: [ ]
341
+ defp remote ( _mod , _fun , _arity ) , do: [ ]
333
342
334
343
@ doc """
335
344
Checks a module is a valid remote.
@@ -353,7 +362,7 @@ defmodule Module.Types.Of do
353
362
if Keyword . get ( meta , :runtime_module , false ) do
354
363
{ :none , context }
355
364
else
356
- case strong_remote ( module , fun , arity ) do
365
+ case remote ( module , fun , arity ) do
357
366
[ ] -> { :none , check_export ( module , fun , arity , meta , stack , context ) }
358
367
clauses -> { { :strong , clauses } , context }
359
368
end
@@ -368,6 +377,9 @@ defmodule Module.Types.Of do
368
377
{ _optional? , value_type } ->
369
378
{ value_type , context }
370
379
380
+ :badtuple ->
381
+ { error_type ( ) , badapply_error ( expr , [ integer ( ) , tuple ] , stack , context ) }
382
+
371
383
reason ->
372
384
{ error_type ( ) , error ( { reason , expr , tuple , index - 1 , context } , meta , stack , context ) }
373
385
end
@@ -386,6 +398,9 @@ defmodule Module.Types.Of do
386
398
value_type when is_descr ( value_type ) ->
387
399
{ value_type , context }
388
400
401
+ :badtuple ->
402
+ { error_type ( ) , badapply_error ( expr , [ integer ( ) , tuple , value ] , stack , context ) }
403
+
389
404
reason ->
390
405
{ error_type ( ) , error ( { reason , expr , tuple , index - 2 , context } , meta , stack , context ) }
391
406
end
@@ -397,6 +412,9 @@ defmodule Module.Types.Of do
397
412
value_type when is_descr ( value_type ) ->
398
413
{ value_type , context }
399
414
415
+ :badtuple ->
416
+ { error_type ( ) , badapply_error ( expr , [ integer ( ) , tuple ] , stack , context ) }
417
+
400
418
reason ->
401
419
{ error_type ( ) , error ( { reason , expr , tuple , index - 1 , context } , meta , stack , context ) }
402
420
end
@@ -412,8 +430,8 @@ defmodule Module.Types.Of do
412
430
{ _ , value_type } ->
413
431
{ value_type , context }
414
432
415
- reason ->
416
- { error_type ( ) , error ( { reason , expr , list , context } , elem ( expr , 1 ) , stack , context ) }
433
+ :badnonemptylist ->
434
+ { error_type ( ) , badapply_error ( expr , [ list ] , stack , context ) }
417
435
end
418
436
end
419
437
@@ -422,8 +440,8 @@ defmodule Module.Types.Of do
422
440
{ _ , value_type } ->
423
441
{ value_type , context }
424
442
425
- reason ->
426
- { error_type ( ) , error ( { reason , expr , list , context } , elem ( expr , 1 ) , stack , context ) }
443
+ :badnonemptylist ->
444
+ { error_type ( ) , badapply_error ( expr , [ list ] , stack , context ) }
427
445
end
428
446
end
429
447
@@ -705,48 +723,6 @@ defmodule Module.Types.Of do
705
723
}
706
724
end
707
725
708
- def format_diagnostic ( { :badnonemptylist , expr , type , context } ) do
709
- traces = collect_traces ( expr , context )
710
-
711
- % {
712
- details: % { typing_traces: traces } ,
713
- message:
714
- IO . iodata_to_binary ( [
715
- """
716
- expected a non-empty list in #{ format_mfa ( expr ) } :
717
-
718
- #{ expr_to_string ( expr ) |> indent ( 4 ) }
719
-
720
- but got type:
721
-
722
- #{ to_quoted_string ( type ) |> indent ( 4 ) }
723
- """ ,
724
- format_traces ( traces )
725
- ] )
726
- }
727
- end
728
-
729
- def format_diagnostic ( { :badtuple , expr , type , _index , context } ) do
730
- traces = collect_traces ( expr , context )
731
-
732
- % {
733
- details: % { typing_traces: traces } ,
734
- message:
735
- IO . iodata_to_binary ( [
736
- """
737
- expected a tuple in #{ format_mfa ( expr ) } :
738
-
739
- #{ expr_to_string ( expr ) |> indent ( 4 ) }
740
-
741
- but got type:
742
-
743
- #{ to_quoted_string ( type ) |> indent ( 4 ) }
744
- """ ,
745
- format_traces ( traces )
746
- ] )
747
- }
748
- end
749
-
750
726
def format_diagnostic ( { :badindex , expr , type , index , context } ) do
751
727
traces = collect_traces ( expr , context )
752
728
@@ -794,23 +770,24 @@ defmodule Module.Types.Of do
794
770
795
771
def format_diagnostic ( { :badapply , expr , args_types , clauses , context } ) do
796
772
traces = collect_traces ( expr , context )
773
+ { { :. , _ , [ mod , fun ] } , _ , args } = expr
797
774
798
775
% {
799
776
details: % { typing_traces: traces } ,
800
777
message:
801
778
IO . iodata_to_binary ( [
802
779
"""
803
- incompatible types given to #{ format_mfa ( expr ) } :
780
+ incompatible types given to #{ format_mfa ( mod , fun , args ) } :
804
781
805
782
#{ expr_to_string ( expr ) |> indent ( 4 ) }
806
783
807
784
expected types:
808
785
809
- #{ clauses_args_to_quoted_string ( clauses ) |> indent ( 4 ) }
786
+ #{ clauses_args_to_quoted_string ( mod , fun , clauses ) |> indent ( 4 ) }
810
787
811
788
but got types:
812
789
813
- #{ args_to_quoted_string ( args_types ) |> indent ( 4 ) }
790
+ #{ args_to_quoted_string ( mod , fun , args_types ) |> indent ( 4 ) }
814
791
""" ,
815
792
format_traces ( traces )
816
793
] )
@@ -936,15 +913,22 @@ defmodule Module.Types.Of do
936
913
match? ( { { :. , _ , [ var , _fun ] } , _ , _args } when is_var ( var ) , expr )
937
914
end
938
915
939
- defp clauses_args_to_quoted_string ( [ { args , _return } ] ) do
940
- args_to_quoted_string ( args )
916
+ defp badapply_error ( { { :. , _ , [ mod , fun ] } , meta , _ } = expr , args_types , stack , context ) do
917
+ clauses = remote ( mod , fun , length ( args_types ) )
918
+ error ( { :badapply , expr , args_types , clauses , context } , meta , stack , context )
919
+ end
920
+
921
+ defp clauses_args_to_quoted_string ( mod , fun , [ { args , _return } ] ) do
922
+ args_to_quoted_string ( mod , fun , args )
941
923
end
942
924
943
- defp args_to_quoted_string ( [ arg ] ) do
925
+ defp args_to_quoted_string ( _mod , _fun , [ arg ] ) do
944
926
to_quoted_string ( arg )
945
927
end
946
928
947
- defp args_to_quoted_string ( args ) do
929
+ defp args_to_quoted_string ( mod , fun , args ) do
930
+ { _mod , _fun , args } = :elixir_rewrite . erl_to_ex ( mod , fun , args )
931
+
948
932
{ :_ , [ ] , Enum . map ( args , & to_quoted / 1 ) }
949
933
|> Code.Formatter . to_algebra ( )
950
934
|> Inspect.Algebra . format ( 98 )
@@ -960,6 +944,10 @@ defmodule Module.Types.Of do
960
944
end
961
945
962
946
defp format_mfa ( { { :. , _ , [ mod , fun ] } , _ , args } ) do
947
+ format_mfa ( mod , fun , args )
948
+ end
949
+
950
+ defp format_mfa ( mod , fun , args ) do
963
951
{ mod , fun , args } = :elixir_rewrite . erl_to_ex ( mod , fun , args )
964
952
Exception . format_mfa ( mod , fun , length ( args ) )
965
953
end
0 commit comments