diff options
-rw-r--r-- | erts/doc/src/erlang.xml | 35 | ||||
-rw-r--r-- | erts/preloaded/ebin/erlang.beam | bin | 84720 -> 84876 bytes | |||
-rw-r--r-- | erts/preloaded/src/erlang.erl | 56 | ||||
-rw-r--r-- | lib/hipe/cerl/erl_bif_types.erl | 150 |
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 Binary files differindex c44f05f87d..01246a34da 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam 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) -> |