aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrik Nyblom <[email protected]>2012-02-01 16:34:08 +0100
committerPatrik Nyblom <[email protected]>2012-02-07 16:00:39 +0100
commit9d870a01dd2fc331b987905b981c52f57a44669f (patch)
treea06c67a291988258a7540a50de163cc64a4c59bb
parentbd941f5020cd50b7532b55454795c2985c372e64 (diff)
downloadotp-9d870a01dd2fc331b987905b981c52f57a44669f.tar.gz
otp-9d870a01dd2fc331b987905b981c52f57a44669f.tar.bz2
otp-9d870a01dd2fc331b987905b981c52f57a44669f.zip
Reintroduce sensitive BIFs in erl_bif_types
This involves exception BIF's, guar BIF's and some other complicated BIF's Also some minor corrections to documentation and specs in erlang.erl Added comment for each spec in erlang.erl shadowed by erl_bif_types. Dialyzer test should now run well except for one or two cases.
-rw-r--r--erts/doc/src/erlang.xml35
-rw-r--r--erts/preloaded/ebin/erlang.beambin84720 -> 84876 bytes
-rw-r--r--erts/preloaded/src/erlang.erl56
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl150
4 files changed, 215 insertions, 26 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 7838cffded..e5ea517492 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -3191,7 +3191,8 @@ os_prompt%</pre>
<type name="priority_level"/>
<fsummary>Set process flag priority for the calling process</fsummary>
<desc>
- <p>This sets the process priority. <c><anno>Level</anno></c> is an atom.
+ <p><marker id="process_flag_priority"></marker>
+ This sets the process priority. <c><anno>Level</anno></c> is an atom.
There are currently four priority levels: <c>low</c>,
<c>normal</c>, <c>high</c>, and <c>max</c>. The default
priority level is <c>normal</c>. <em>NOTE</em>: The
@@ -3333,6 +3334,8 @@ os_prompt%</pre>
<func>
<name name="process_info" arity="1"/>
<type name="process_info_result_item"/>
+ <type name="priority_level"/>
+ <type name="stack_item"/>
<fsummary>Information about a process</fsummary>
<desc>
<p>Returns a list containing <c><anno>InfoTuple</anno></c>s with
@@ -3889,7 +3892,7 @@ true</pre>
<p>Starts a timer which will send the message <c>Msg</c>
to <c><anno>Dest</anno></c> after <c><anno>Time</anno></c> milliseconds.</p>
<p>If <c><anno>Dest</anno></c> is a <c>pid()</c> it has to be a <c>pid()</c> of a local process, dead or alive.</p>
- <p>The <c><anno>Time</anno></c> value can, in the current implementation, not be grater than 4294967295.</p>
+ <p>The <c><anno>Time</anno></c> value can, in the current implementation, not be greater than 4294967295.</p>
<p>If <c><anno>Dest</anno></c> is an <c>atom()</c>, it is supposed to be the name of
a registered process. The process referred to by the name is
looked up at the time of delivery. No error is given if
@@ -4314,7 +4317,7 @@ true</pre>
<c>{timeout, <anno>TimerRef</anno>, <anno>Msg</anno>}</c> to <c><anno>Dest</anno></c>
after <c><anno>Time</anno></c> milliseconds.</p>
<p>If <c><anno>Dest</anno></c> is a <c>pid()</c> it has to be a <c>pid()</c> of a local process, dead or alive.</p>
- <p>The <c><anno>Time</anno></c> value can, in the current implementation, not be grater than 4294967295.</p>
+ <p>The <c><anno>Time</anno></c> value can, in the current implementation, not be greater than 4294967295.</p>
<p>If <c><anno>Dest</anno></c> is an <c>atom()</c>, it is supposed to be the name of
a registered process. The process referred to by the name is
looked up at the time of delivery. No error is given if
@@ -4345,7 +4348,8 @@ true</pre>
<name name="statistics" arity="1" clause_i="2"/>
<fsummary>Information about exact reductions</fsummary>
<desc>
- <p><em>NOTE:</em> <c>statistics(exact_reductions)</c> is
+ <p><marker id="statistics_exact_reductions"></marker>
+ <em>NOTE:</em> <c>statistics(exact_reductions)</c> is
a more expensive operation than
<seealso marker="#statistics_reductions">statistics(reductions)</seealso>
especially on an Erlang machine with SMP support.</p>
@@ -4371,7 +4375,8 @@ true</pre>
<name name="statistics" arity="1" clause_i="5"/>
<fsummary>Information about reductions</fsummary>
<desc>
- <p><em>NOTE:</em> From erts version 5.5 (OTP release R11B)
+ <p><marker id="statistics_reductions"></marker>
+ <em>NOTE:</em> From erts version 5.5 (OTP release R11B)
this value does not include reductions performed in current
time slices of currently scheduled processes. If an
exact value is wanted, use
@@ -4525,12 +4530,14 @@ true</pre>
<name name="system_flag" arity="2" clause_i="2"/>
<type name="cpu_topology"/>
<type name="level_entry"/>
- <type name="sub_level"/>
<type name="level_tag"/>
+ <type name="sub_level"/>
+ <type name="info_list"/>
<fsummary>Set system flag cpu_topology</fsummary>
<desc>
<warning>
- <p>This argument is <em>deprecated</em> and
+ <p><marker id="system_flag_cpu_topology"></marker>
+ This argument is <em>deprecated</em> and
scheduled for removal in erts-5.10/OTP-R16. Instead of using
this argument you are advised to use the <c>erl</c> command
line argument <seealso marker="erts:erl#+sct">+sct</seealso>.
@@ -4616,7 +4623,8 @@ true</pre>
<name name="system_flag" arity="2" clause_i="6"/>
<fsummary>Set system flag multi_scheduling</fsummary>
<desc>
- <p>If multi-scheduling is enabled, more than one scheduler
+ <p><marker id="system_flag_multi_scheduling"></marker>
+ If multi-scheduling is enabled, more than one scheduler
thread is used by the emulator. Multi-scheduling can be
blocked. When multi-scheduling has been blocked, only
one scheduler thread will schedule Erlang processes.</p>
@@ -4655,7 +4663,8 @@ true</pre>
<fsummary>Set system flag scheduler_bind_type</fsummary>
<desc>
<warning>
- <p>This argument is <em>deprecated</em> and
+ <p><marker id="system_flag_scheduler_bind_type"></marker>
+ This argument is <em>deprecated</em> and
scheduled for removal in erts-5.10/OTP-R16. Instead of using
this argument you are advised to use the <c>erl</c> command
line argument <seealso marker="erts:erl#+sbt">+sbt</seealso>.
@@ -4772,7 +4781,8 @@ true</pre>
<name name="system_flag" arity="2" clause_i="8"/>
<fsummary>Set system flag schedulers_online</fsummary>
<desc>
- <p>Sets the amount of schedulers online. Valid range is
+ <p><marker id="system_flag_schedulers_online"></marker>
+ Sets the amount of schedulers online. Valid range is
<![CDATA[1 <= SchedulersOnline <= erlang:system_info(schedulers)]]>.
</p>
<p>Returns the old value of the flag.</p>
@@ -4932,6 +4942,7 @@ true</pre>
<type name="cpu_topology"/>
<type name="level_entry"/>
<type_desc name="cpu_topology">
+ <marker id="system_info_cpu_topology"></marker>
All <c><anno>LevelEntry</anno></c>s of a list
must contain the same <c><anno>LevelTag</anno></c>, except
on the top level where both <c>node</c> and
@@ -4956,7 +4967,7 @@ true</pre>
of the current system
(emulator) as specified by <c><anno>Item</anno></c>:</p>
<taglist>
- <tag><marker id="system_info_cpu_topology"><c>cpu_topology</c></marker></tag>
+ <tag><c>cpu_topology</c></tag>
<item>
<p>Returns the <c><anno>CpuTopology</anno></c> which currently is used by the
emulator. The CPU topology is used when binding schedulers
@@ -6188,6 +6199,8 @@ true</pre>
<name name="trace_info" arity="2"/>
<type name="trace_info_return"/>
<type name="trace_info_item_result"/>
+ <type name="trace_info_flag"/>
+ <type name="trace_match_spec"/>
<fsummary>Trace information about a process or function</fsummary>
<desc>
<p>Returns trace information about a process or function.</p>
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index c44f05f87d..01246a34da 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index b1b2156ad5..65ebe83c3a 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -117,7 +117,7 @@
is_record/3, is_reference/1, is_tuple/1, load_module/2,
load_nif/2, localtime_to_universaltime/2, make_fun/3,
make_tuple/2, make_tuple/3, nodes/1, open_port/2,
- port_call/3, port_info/1, port_info/2, process_flag/2,
+ port_call/2, port_call/3, port_info/1, port_info/2, process_flag/2,
process_info/2, send/2, send/3, seq_trace_info/1,
setelement/3, spawn_opt/1,
statistics/1, subtract/2, system_flag/2,
@@ -579,12 +579,14 @@ erase(_Key) ->
erlang:nif_error(undefined).
% error/1
+%% Shadowed by erl_bif_types: erlang:error/1
-spec error(Reason) -> no_return() when
Reason :: term().
error(_Reason) ->
erlang:nif_error(undefined).
% error/2
+%% Shadowed by erl_bif_types: erlang:error/2
-spec error(Reason, Args) -> no_return() when
Reason :: term(),
Args :: [term()].
@@ -592,6 +594,7 @@ error(_Reason, _Args) ->
erlang:nif_error(undefined).
% exit/1
+%% Shadowed by erl_bif_types: erlang:exit/1
-spec exit(Reason) -> no_return() when
Reason :: term().
exit(_Reason) ->
@@ -719,11 +722,13 @@ group_leader(_GroupLeader, _Pid) ->
erlang:nif_error(undefined).
% halt/0
+%% Shadowed by erl_bif_types: erlang:halt/0
-spec halt() -> no_return().
halt() ->
erlang:nif_error(undefined).
% halt/1
+%% Shadowed by erl_bif_types: erlang:halt/1
-spec halt(Status) -> no_return() when
Status :: non_neg_integer() | string().
halt(_Status) ->
@@ -934,12 +939,14 @@ monitor_node(_Node, _Flag, _Options) ->
erlang:nif_error(undefined).
% nif_error/1
+%% Shadowed by erl_bif_types: erlang:nif_error/1
-spec erlang:nif_error(Reason) -> no_return() when
Reason :: term().
nif_error(_Reason) ->
erlang:nif_error(undefined).
% nif_error/2
+%% Shadowed by erl_bif_types: erlang:nif_error/2
-spec erlang:nif_error(Reason, Args) -> no_return() when
Reason :: term(),
Args :: [term()].
@@ -1293,6 +1300,7 @@ system_profile(_ProfilerPid, _Options) ->
erlang:nif_error(undefined).
% throw/1
+%% Shadowed by erl_bif_types: erlang:throw/1
-spec throw(Any) -> no_return() when
Any :: term().
throw(_Any) ->
@@ -1380,6 +1388,7 @@ whereis(_RegName) ->
%% types and specs
+%% Shadowed by erl_bif_types: erlang:abs/1
-spec abs(Float) -> float() when
Float :: float();
(Int) -> non_neg_integer() when
@@ -1388,12 +1397,14 @@ abs(_Number) ->
erlang:nif_error(undefined).
%% Not documented
+%% Shadowed by erl_bif_types: erlang:append/2
-spec erlang:append(List,Tail) -> maybe_improper_list() when
List :: [term()],
Tail :: term().
append(_List,_Tail) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:element/2
-spec element(N, Tuple) -> term() when
N :: pos_integer(),
Tuple :: tuple().
@@ -1408,6 +1419,7 @@ element(_N, _Tuple) ->
get_module_info(_Module, _Item) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:hd/1
-spec hd(List) -> term() when
List :: [term(), ...].
hd(_List) ->
@@ -1415,73 +1427,87 @@ hd(_List) ->
%% erlang:info/1 no longer exists!
+%% Shadowed by erl_bif_types: erlang:is_atom/1
-spec is_atom(Term) -> boolean() when
Term :: term().
is_atom(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_binary/1
-spec is_binary(Term) -> boolean() when
Term :: term().
is_binary(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_bitstring/1
-spec is_bitstring(Term) -> boolean() when
Term :: term().
is_bitstring(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_boolean/1
-spec is_boolean(Term) -> boolean() when
Term :: term().
is_boolean(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_float/1
-spec is_float(Term) -> boolean() when
Term :: term().
is_float(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_function/1
-spec is_function(Term) -> boolean() when
Term :: term().
is_function(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_function/2
-spec is_function(Term, Arity) -> boolean() when
Term :: term(),
Arity :: arity().
is_function(_Term, _Arity) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_integer/1
-spec is_integer(Term) -> boolean() when
Term :: term().
is_integer(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_list/1
-spec is_list(Term) -> boolean() when
Term :: term().
is_list(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_number/1
-spec is_number(Term) -> boolean() when
Term :: term().
is_number(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_pid/1
-spec is_pid(Term) -> boolean() when
Term :: term().
is_pid(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_port/1
-spec is_port(Term) -> boolean() when
Term :: term().
is_port(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_record/2
-spec is_record(Term,RecordTag) -> boolean() when
Term :: term(),
RecordTag :: atom().
is_record(_Term,_RecordTag) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_record/3
-spec is_record(Term,RecordTag,Size) -> boolean() when
Term :: term(),
RecordTag :: atom(),
@@ -1489,11 +1515,13 @@ is_record(_Term,_RecordTag) ->
is_record(_Term,_RecordTag,_Size) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_reference/1
-spec is_reference(Term) -> boolean() when
Term :: term().
is_reference(_Term) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:is_tuple/1
-spec is_tuple(Term) -> boolean() when
Term :: term().
is_tuple(_Term) ->
@@ -1531,12 +1559,14 @@ localtime_to_universaltime(_Localtime, _IsDst) ->
make_fun(_Module,_Function, _Arity) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:make_tuple/2
-spec erlang:make_tuple(Arity, InitialValue) -> tuple() when
Arity :: arity(),
InitialValue :: term().
make_tuple(_Arity,_InitialValue) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:make_tuple/3
-spec erlang:make_tuple(Arity, DefaultValue, InitList) -> tuple() when
Arity :: arity(),
DefaultValue :: term(),
@@ -1575,6 +1605,14 @@ nodes(_Arg) ->
open_port(_PortName,_PortSettings) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:port_call/2
+-spec erlang:port_call(Port, Data) -> term() when
+ Port :: port() | atom(),
+ Data :: term().
+port_call(_Port, _Data) ->
+ erlang:nif_error(undefined).
+
+%% Shadowed by erl_bif_types: erlang:port_call/3
-spec erlang:port_call(Port, Operation, Data) -> term() when
Port :: port() | atom(),
Operation :: integer(),
@@ -1600,16 +1638,18 @@ port_call(_Port, _Operation, _Data) ->
{input, Bytes :: non_neg_integer()} |
{output, Bytes :: non_neg_integer()}.
+%% Shadowed by erl_bif_types: erlang:port_info/1
-spec erlang:port_info(Port) -> Result when
Port :: port() | atom(),
Result :: [port_info_result_item()] | undefined.
port_info(_Result) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:port_info/2
-spec erlang:port_info(Port, Item) -> Result when
Port :: port() | atom(),
Item :: port_info_item(),
- Result :: port_info_result_item() | undefined | [].
+ Result :: port_info_result_item() | undefined.
port_info(_Result, _Item) ->
erlang:nif_error(undefined).
@@ -1689,7 +1729,7 @@ process_flag(_Flag, _Value) ->
{current_location,
{Module :: module(), Function :: atom(), Arity :: arity(),
Location :: [{file, Filename :: string()} | % not a stack_item()!
- {line, Line :: integer()}]}} |
+ {line, Line :: pos_integer()}]}} |
{current_stacktrace, Stack :: [stack_item()]} |
{dictionary, Dictionary :: [{Key :: term(), Value :: term()}]} |
{error_handler, Module :: module()} |
@@ -1728,7 +1768,7 @@ process_flag(_Flag, _Value) ->
Function :: atom(),
Arity :: arity() | (Args :: [term()]),
Location :: [{file, Filename :: string()} |
- {line, Line :: integer()}]}.
+ {line, Line :: pos_integer()}]}.
-spec process_info(Pid, Item) ->
InfoTuple | [] | undefined when
@@ -1744,7 +1784,7 @@ process_flag(_Flag, _Value) ->
process_info(_Pid,_ItemSpec) ->
erlang:nif_error(undefined).
--spec send(Dest, Msg) -> Msg when
+-spec erlang:send(Dest, Msg) -> Msg when
Dest :: dst(),
Msg :: term().
send(_Dest,_Msg) ->
@@ -1768,6 +1808,7 @@ send(_Dest,_Msg,_Options) ->
seq_trace_info(_What) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:setelement/3
-spec setelement(Index, Tuple1, Value) -> Tuple2 when
Index :: pos_integer(),
Tuple1 :: tuple(),
@@ -1817,6 +1858,7 @@ statistics(_Item) ->
erlang:nif_error(undefined).
%% Not documented
+%% Shadowed by erl_bif_types: erlang:subtract/2
-spec erlang:subtract([term()], [term()]) -> [term()].
subtract(_,_) ->
erlang:nif_error(undefined).
@@ -1881,6 +1923,7 @@ term_to_binary(_Term) ->
term_to_binary(_Term, _Options) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:tl/1
-spec tl(List) -> term() when
List :: [term(), ...].
tl(_List) ->
@@ -1916,6 +1959,7 @@ trace_pattern(_MFA, _MatchSpec) ->
trace_pattern(_MFA, _MatchSpec, _FlagList) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:tuple_to_list/1
-spec tuple_to_list(Tuple) -> [term()] when
Tuple :: tuple().
tuple_to_list(_Tuple) ->
@@ -1934,6 +1978,7 @@ tuple_to_list(_Tuple) ->
-type info_list() :: [].
%% Note: changing the ordering number of a clause will change the docs!
+%% Shadowed by erl_bif_types: erlang:system_info/1
-spec erlang:system_info
(allocated_areas) -> [ tuple() ];
(allocator) ->
@@ -2031,6 +2076,7 @@ universaltime_to_localtime(_Universaltime) ->
apply(Fun, Args) ->
erlang:apply(Fun, Args).
+%% Shadowed by erl_bif_types: erlang:apply/3
-spec apply(Module, Function, Args) -> term() when
Module :: module(),
Function :: atom(),
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 190f14a474..b822f182c2 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -63,6 +63,7 @@
t_fun/2,
t_fun_args/1,
t_fun_range/1,
+ t_identifier/0,
t_inf/2,
t_integer/0,
t_integer/1,
@@ -138,6 +139,12 @@ type(M, F, A) ->
-spec type(atom(), atom(), arity(), [erl_types:erl_type()]) -> erl_types:erl_type().
%%-- erlang -------------------------------------------------------------------
+type(erlang, halt, 0, _) -> t_none();
+type(erlang, halt, 1, _) -> t_none();
+type(erlang, exit, 1, _) -> t_none();
+type(erlang, error, 1, _) -> t_none();
+type(erlang, error, 2, _) -> t_none();
+type(erlang, throw, 1, _) -> t_none();
type(erlang, '==', 2, Xs = [X1, X2]) ->
case t_is_atom(X1) andalso t_is_atom(X2) of
true -> type(erlang, '=:=', 2, Xs);
@@ -489,6 +496,9 @@ type(erlang, 'bnot', 1, Xs) ->
{ok, T} -> T
end
end);
+%% Guard bif, needs to be here.
+type(erlang, abs, 1, Xs) ->
+ strict(arg_types(erlang, abs, 1), Xs, fun ([X]) -> X end);
%% This returns (-X)-1, so it often gives a negative result.
%% strict(arg_types(erlang, 'bnot', 1), Xs, fun (_) -> t_integer() end);
type(erlang, append, 2, Xs) -> type(erlang, '++', 2, Xs); % alias
@@ -504,8 +514,24 @@ type(erlang, apply, 2, Xs) ->
strict(arg_types(erlang, apply, 2), Xs, Fun);
type(erlang, apply, 3, Xs) ->
strict(arg_types(erlang, apply, 3), Xs, fun (_) -> t_any() end);
+%% Guard bif, needs to be here.
+type(erlang, binary_part, 2, Xs) ->
+ strict(arg_types(erlang, binary_part, 2), Xs, fun (_) -> t_binary() end);
+%% Guard bif, needs to be here.
+type(erlang, binary_part, 3, Xs) ->
+ strict(arg_types(erlang, binary_part, 3), Xs, fun (_) -> t_binary() end);
+%% Guard bif, needs to be here.
+type(erlang, bit_size, 1, Xs) ->
+ strict(arg_types(erlang, bit_size, 1), Xs,
+ fun (_) -> t_non_neg_integer() end);
+%% Guard bif, needs to be here.
+type(erlang, byte_size, 1, Xs) ->
+ strict(arg_types(erlang, byte_size, 1), Xs,
+ fun (_) -> t_non_neg_integer() end);
type(erlang, disconnect_node, 1, Xs) ->
strict(arg_types(erlang, disconnect_node, 1), Xs, fun (_) -> t_sup([t_boolean(), t_atom('ignored')]) end);
+%% Guard bif, needs to be here.
+%% Also much more expressive than anything you could write in a spec...
type(erlang, element, 2, Xs) ->
strict(arg_types(erlang, element, 2), Xs,
fun ([X1, X2]) ->
@@ -529,16 +555,22 @@ type(erlang, element, 2, Xs) ->
t_sup([type(erlang, element, 2, [X1, Y]) || Y <- Ts])
end
end);
+%% Guard bif, needs to be here.
+type(erlang, float, 1, Xs) ->
+ strict(arg_types(erlang, float, 1), Xs, fun (_) -> t_float() end);
type(erlang, fun_info, 1, Xs) ->
strict(arg_types(erlang, fun_info, 1), Xs,
fun (_) -> t_list(t_tuple([t_atom(), t_any()])) end);
type(erlang, get_cookie, 0, _) -> t_atom(); % | t_atom('nocookie')
+%% Guard bif, needs to be here.
type(erlang, hd, 1, Xs) ->
strict(arg_types(erlang, hd, 1), Xs, fun ([X]) -> t_cons_hd(X) end);
type(erlang, integer_to_list, 2, Xs) ->
strict(arg_types(erlang, integer_to_list, 2), Xs,
fun (_) -> t_string() end);
type(erlang, info, 1, Xs) -> type(erlang, system_info, 1, Xs); % alias
+%% All type tests are guard BIF's and may be implemented in ways that
+%% cannot be expressed in a type spec, why they are kept in erl_bif_types.
type(erlang, is_atom, 1, Xs) ->
Fun = fun (X) -> check_guard(X, fun (Y) -> t_is_atom(Y) end, t_atom()) end,
strict(arg_types(erlang, is_atom, 1), Xs, Fun);
@@ -702,6 +734,9 @@ type(erlang, is_tuple, 1, Xs) ->
check_guard(X, fun (Y) -> t_is_tuple(Y) end, t_tuple())
end,
strict(arg_types(erlang, is_tuple, 1), Xs, Fun);
+%% Guard bif, needs to be here.
+type(erlang, length, 1, Xs) ->
+ strict(arg_types(erlang, length, 1), Xs, fun (_) -> t_non_neg_fixnum() end);
type(erlang, list_to_integer, 2, Xs) ->
strict(arg_types(erlang, list_to_integer, 2), Xs,
fun (_) -> t_integer() end);
@@ -726,12 +761,47 @@ type(erlang, nif_error, 1, _) ->
t_any(); % this BIF and the next one are stubs for NIFs and never return
type(erlang, nif_error, 2, Xs) ->
strict(arg_types(erlang, nif_error, 2), Xs, fun (_) -> t_any() end);
+%% Guard bif, needs to be here.
+type(erlang, node, 0, _) -> t_node();
+%% Guard bif, needs to be here.
+type(erlang, node, 1, Xs) ->
+ strict(arg_types(erlang, node, 1), Xs, fun (_) -> t_node() end);
type(erlang, nodes, 0, _) -> t_list(t_node());
type(erlang, port_call, Arity, Xs) when Arity =:= 2; Arity =:= 3 ->
strict(arg_types(erlang, port_call, Arity), Xs, fun (_) -> t_any() end);
type(erlang, port_info, 1, Xs) ->
strict(arg_types(erlang, port_info, 1), Xs,
fun (_) -> t_sup(t_atom('undefined'), t_list()) end);
+type(erlang, port_info, 2, Xs) ->
+ strict(arg_types(erlang, port_info, 2), Xs,
+ fun ([_Port, Item]) ->
+ t_sup(t_atom('undefined'),
+ case t_atom_vals(Item) of
+ ['connected'] -> t_tuple([Item, t_pid()]);
+ ['id'] -> t_tuple([Item, t_integer()]);
+ ['input'] -> t_tuple([Item, t_integer()]);
+ ['links'] -> t_tuple([Item, t_list(t_pid())]);
+ ['name'] -> t_tuple([Item, t_string()]);
+ ['output'] -> t_tuple([Item, t_integer()]);
+ ['registered_name'] -> t_tuple([Item, t_atom()]);
+ List when is_list(List) ->
+ t_tuple([t_sup([t_atom(A) || A <- List]),
+ t_sup([t_atom(), t_integer(),
+ t_pid(), t_list(t_pid()),
+ t_string()])]);
+ unknown ->
+ [_, PosItem] = arg_types(erlang, port_info, 2),
+ t_tuple([PosItem,
+ t_sup([t_atom(), t_integer(),
+ t_pid(), t_list(t_pid()),
+ t_string()])])
+ end)
+ end);
+%% Guard bif, needs to be here.
+type(erlang, round, 1, Xs) ->
+ strict(arg_types(erlang, round, 1), Xs, fun (_) -> t_integer() end);
+%% Guard bif, needs to be here.
+type(erlang, self, 0, _) -> t_pid();
type(erlang, set_cookie, 2, Xs) ->
strict(arg_types(erlang, set_cookie, 2), Xs, fun (_) -> t_atom('true') end);
type(erlang, setelement, 3, Xs) ->
@@ -765,6 +835,9 @@ type(erlang, setelement, 3, Xs) ->
t_sup([type(erlang, setelement, 3, [X1, Y, X3]) || Y <- Ts])
end
end);
+%% Guard bif, needs to be here.
+type(erlang, size, 1, Xs) ->
+ strict(arg_types(erlang, size, 1), Xs, fun (_) -> t_non_neg_integer() end);
type(erlang, spawn, 1, Xs) ->
strict(arg_types(erlang, spawn, 1), Xs, fun (_) -> t_pid() end);
type(erlang, spawn, 2, Xs) ->
@@ -894,13 +967,15 @@ type(erlang, system_info, 1, Xs) ->
t_any() %% overapproximation as the return value might change
end
end);
-type(erlang, term_to_binary, 1, Xs) ->
- strict(arg_types(erlang, term_to_binary, 1), Xs, fun (_) -> t_binary() end);
+%% Guard bif, needs to be here.
type(erlang, tl, 1, Xs) ->
strict(arg_types(erlang, tl, 1), Xs, fun ([X]) -> t_cons_tl(X) end);
-type(erlang, trace_pattern, 2, Xs) ->
- strict(arg_types(erlang, trace_pattern, 2), Xs,
- fun (_) -> t_non_neg_fixnum() end); %% num of MFAs that match pattern
+%% Guard bif, needs to be here.
+type(erlang, trunc, 1, Xs) ->
+ strict(arg_types(erlang, trunc, 1), Xs, fun (_) -> t_integer() end);
+%% Guard bif, needs to be here.
+type(erlang, tuple_size, 1, Xs) ->
+ strict(arg_types(erlang, tuple_size, 1), Xs, fun (_) -> t_non_neg_integer() end);
type(erlang, tuple_to_list, 1, Xs) ->
strict(arg_types(erlang, tuple_to_list, 1), Xs,
fun ([X]) ->
@@ -2092,6 +2167,9 @@ arg_types(erlang, 'bsl', 2) ->
[t_integer(), t_integer()];
arg_types(erlang, 'bnot', 1) ->
[t_integer()];
+%% Guard bif, needs to be here.
+arg_types(erlang, abs, 1) ->
+ [t_number()];
arg_types(erlang, append, 2) ->
arg_types(erlang, '++', 2);
arg_types(erlang, apply, 2) ->
@@ -2101,14 +2179,41 @@ arg_types(erlang, apply, 2) ->
t_list()];
arg_types(erlang, apply, 3) ->
[t_sup(t_atom(), t_tuple()), t_atom(), t_list()];
+%% Guard bif, needs to be here.
+arg_types(erlang, binary_part, 2) ->
+ [t_binary(), t_tuple([t_non_neg_integer(), t_integer()])];
+%% Guard bif, needs to be here.
+arg_types(erlang, binary_part, 3) ->
+ [t_binary(), t_non_neg_integer(), t_integer()];
+%% Guard bif, needs to be here.
+arg_types(erlang, bit_size, 1) ->
+ [t_bitstr()];
+%% Guard bif, needs to be here.
+arg_types(erlang, byte_size, 1) ->
+ [t_binary()];
arg_types(erlang, disconnect_node, 1) ->
[t_node()];
+arg_types(erlang, halt, 0) ->
+ [];
+arg_types(erlang, halt, 1) ->
+ [t_sup(t_non_neg_fixnum(), t_string())];
+arg_types(erlang, error, 1) ->
+ [t_any()];
+arg_types(erlang, error, 2) ->
+ [t_any(), t_list()];
+arg_types(erlang, exit, 1) ->
+ [t_any()];
+%% Guard bif, needs to be here.
arg_types(erlang, element, 2) ->
[t_pos_fixnum(), t_tuple()];
+%% Guard bif, needs to be here.
+arg_types(erlang, float, 1) ->
+ [t_number()];
arg_types(erlang, fun_info, 1) ->
[t_fun()];
arg_types(erlang, get_cookie, 0) ->
[];
+%% Guard bif, needs to be here.
arg_types(erlang, hd, 1) ->
[t_cons()];
arg_types(erlang, info, 1) ->
@@ -2149,6 +2254,9 @@ arg_types(erlang, is_reference, 1) ->
[t_any()];
arg_types(erlang, is_tuple, 1) ->
[t_any()];
+%% Guard bif, needs to be here.
+arg_types(erlang, length, 1) ->
+ [t_list()];
arg_types(erlang, list_to_integer, 2) ->
[t_list(t_byte()), t_from_range(2, 36)];
arg_types(erlang, make_tuple, 2) ->
@@ -2161,6 +2269,12 @@ arg_types(erlang, nif_error, 1) ->
[t_any()];
arg_types(erlang, nif_error, 2) ->
[t_any(), t_list()];
+%% Guard bif, needs to be here.
+arg_types(erlang, node, 0) ->
+ [];
+%% Guard bif, needs to be here.
+arg_types(erlang, node, 1) ->
+ [t_identifier()];
arg_types(erlang, nodes, 0) ->
[];
arg_types(erlang, port_call, 2) ->
@@ -2169,10 +2283,23 @@ arg_types(erlang, port_call, 3) ->
[t_sup(t_port(), t_atom()), t_integer(), t_any()];
arg_types(erlang, port_info, 1) ->
[t_sup(t_port(), t_atom())];
+arg_types(erlang, port_info, 2) ->
+ [t_sup(t_port(), t_atom()),
+ t_atoms(['registered_name', 'id', 'connected',
+ 'links', 'name', 'input', 'output'])];
+%% Guard bif, needs to be here.
+arg_types(erlang, round, 1) ->
+ [t_number()];
+%% Guard bif, needs to be here.
+arg_types(erlang, self, 0) ->
+ [];
arg_types(erlang, set_cookie, 2) ->
[t_node(), t_atom()];
arg_types(erlang, setelement, 3) ->
[t_pos_integer(), t_tuple(), t_any()];
+%% Guard bif, needs to be here.
+arg_types(erlang, size, 1) ->
+ [t_sup(t_tuple(), t_binary())];
arg_types(erlang, spawn, 1) -> %% TODO: Tuple?
[t_fun()];
arg_types(erlang, spawn, 2) -> %% TODO: Tuple?
@@ -2194,14 +2321,17 @@ arg_types(erlang, system_info, 1) ->
t_tuple([t_atom(), t_any()]), % documented
t_tuple([t_atom(), t_atom(), t_any()]),
t_tuple([t_atom(allocator_sizes), t_reference(), t_any()])])];
-arg_types(erlang, term_to_binary, 1) ->
+arg_types(erlang, throw, 1) ->
[t_any()];
+%% Guard bif, needs to be here.
arg_types(erlang, tl, 1) ->
[t_cons()];
-arg_types(erlang, trace_pattern, 2) ->
- [t_sup(t_tuple([t_atom(), t_atom(), t_sup(t_arity(), t_atom('_'))]),
- t_atom('on_load')),
- t_sup([t_boolean(), t_list(), t_atom('restart'), t_atom('pause')])];
+%% Guard bif, needs to be here.
+arg_types(erlang, trunc, 1) ->
+ [t_number()];
+%% Guard bif, needs to be here.
+arg_types(erlang, tuple_size, 1) ->
+ [t_tuple()];
arg_types(erlang, tuple_to_list, 1) ->
[t_tuple()];
arg_types(erlang, yield, 0) ->