@@ -387,8 +387,10 @@ defmodule Kernel.Typespec do
387
387
388
388
line = line ( meta )
389
389
vars = Keyword . keys ( guard )
390
- { fun_args , state } = fn_args ( meta , args , return , vars , caller , state )
391
- spec = { :type , line , :fun , fun_args }
390
+
391
+ { args , state } = :lists . mapfoldl ( & typespec ( & 1 , vars , caller , & 2 ) , state , args )
392
+ { return , state } = typespec ( return , vars , caller , state )
393
+ spec = { :type , line , :fun , [ { :type , line , :product , args } , return ] }
392
394
393
395
{ spec , state } =
394
396
case guard_to_constraints ( guard , vars , meta , caller , state ) do
@@ -657,8 +659,16 @@ defmodule Kernel.Typespec do
657
659
# Handle funs
658
660
defp typespec ( [ { :-> , meta , [ args , return ] } ] , vars , caller , state )
659
661
when is_list ( args ) do
660
- { args , state } = fn_args ( meta , args , return , vars , caller , state )
661
- { { :type , line ( meta ) , :fun , args } , state }
662
+ { args , state } = fn_args ( meta , args , vars , caller , state )
663
+ { spec , state } = typespec ( return , vars , caller , state )
664
+
665
+ fun_args =
666
+ case [ args , spec ] do
667
+ [ { :type , _ , :any } , { :type , _ , :any , [ ] } ] -> [ ]
668
+ pair -> pair
669
+ end
670
+
671
+ { { :type , line ( meta ) , :fun , fun_args } , state }
662
672
end
663
673
664
674
# Handle type operator
@@ -848,6 +858,14 @@ defmodule Kernel.Typespec do
848
858
{ { :type , line ( meta ) , :fun , args } , state }
849
859
end
850
860
861
+ defp typespec ( { :... , _meta , _args } , _vars , caller , _state ) do
862
+ compile_error (
863
+ caller ,
864
+ "... in typespecs is only allowed inside lists, as in [term(), ...], " <>
865
+ "or inside functions, as in (... -> term())"
866
+ )
867
+ end
868
+
851
869
defp typespec ( { name , meta , args } , vars , caller , state ) when is_atom ( name ) do
852
870
{ args , state } = :lists . mapfoldl ( & typespec ( & 1 , vars , caller , & 2 ) , state , args )
853
871
arity = length ( args )
@@ -977,16 +995,6 @@ defmodule Kernel.Typespec do
977
995
compile_error ( caller , message )
978
996
end
979
997
980
- defp fn_args ( meta , args , return , vars , caller , state ) do
981
- { fun_args , state } = fn_args ( meta , args , vars , caller , state )
982
- { spec , state } = typespec ( return , vars , caller , state )
983
-
984
- case [ fun_args , spec ] do
985
- [ { :type , _ , :any } , { :type , _ , :any , [ ] } ] -> { [ ] , state }
986
- x -> { x , state }
987
- end
988
- end
989
-
990
998
defp fn_args ( meta , [ { :... , _ , _ } ] , _vars , _caller , state ) do
991
999
{ { :type , line ( meta ) , :any } , state }
992
1000
end
0 commit comments