Skip to content

Commit 29a385c

Browse files
committed
Type checking of all Kernel inlined functions
1 parent 771cfe6 commit 29a385c

File tree

2 files changed

+56
-12
lines changed

2 files changed

+56
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ TODO.
44

55
## Type system improvements
66

7-
* Type checking and inference of patterns
7+
* Type inference of patterns (typing inference of guards will be part of an upcoming release)
88

99
* [Support for tuples and lists as composite types](https://elixir-lang.org/blog/2024/08/28/typing-lists-and-tuples/) as well as type checking of its basic operations from Kernel
1010

11+
* Type checking of all guards
12+
1113
* Type checking of all built-in conversion functions, such as `List.to_integer/1` and `Atom.to_string/1`
1214

13-
* Type checking of all functions in `Kernel` which are inlined by the compiler
15+
* Type checking of all functions in `Kernel` which are inlined by the compiler (except `apply/2` and `apply/3`)
1416

1517
* Type checking of all functions in the `Tuple` module
1618

lib/elixir/lib/module/types/of.ex

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,19 @@ defmodule Module.Types.Of do
335335
{[float(), float()], float()}
336336
]
337337

338+
is_clauses = [{[term()], boolean()}]
339+
338340
for {mod, fun, clauses} <- [
339341
# :binary
340342
{:binary, :copy, [{[binary(), integer()], binary()}]},
341343

342344
# :erlang
345+
{:erlang, :+, [{[integer()], integer()}, {[float()], float()}]},
343346
{:erlang, :+, basic_arith_2_args_clauses},
347+
{:erlang, :-, [{[integer()], integer()}, {[float()], float()}]},
344348
{:erlang, :-, basic_arith_2_args_clauses},
345349
{:erlang, :*, basic_arith_2_args_clauses},
350+
{:erlang, :/, [{[union(integer(), float()), union(integer(), float())], float()}]},
346351
{:erlang, :"/=", [{[term(), term()], boolean()}]},
347352
{:erlang, :"=/=", [{[term(), term()], boolean()}]},
348353
{:erlang, :<, [{[term(), term()], boolean()}]},
@@ -351,53 +356,90 @@ defmodule Module.Types.Of do
351356
{:erlang, :"=:=", [{[term(), term()], boolean()}]},
352357
{:erlang, :>, [{[term(), term()], boolean()}]},
353358
{:erlang, :>=, [{[term(), term()], boolean()}]},
359+
{:erlang, :abs, [{[integer()], integer()}, {[float()], float()}]},
354360
{:erlang, :atom_to_binary, [{[atom()], binary()}]},
355361
{:erlang, :atom_to_list, [{[atom()], list(integer())}]},
356362
{:erlang, :band, [{[integer(), integer()], integer()}]},
363+
{:erlang, :binary_part, [{[binary(), integer(), integer()], binary()}]},
357364
{:erlang, :binary_to_atom, [{[binary()], atom()}]},
358365
{:erlang, :binary_to_existing_atom, [{[binary()], atom()}]},
359366
{:erlang, :binary_to_integer, [{[binary()], integer()}]},
360367
{:erlang, :binary_to_integer, [{[binary(), integer()], integer()}]},
361368
{:erlang, :binary_to_float, [{[binary()], float()}]},
369+
{:erlang, :bit_size, [{[binary()], integer()}]},
362370
{:erlang, :bnot, [{[integer()], integer()}]},
363371
{:erlang, :bor, [{[integer(), integer()], integer()}]},
364372
{:erlang, :bsl, [{[integer(), integer()], integer()}]},
365373
{:erlang, :bsr, [{[integer(), integer()], integer()}]},
366374
{:erlang, :bxor, [{[integer(), integer()], integer()}]},
375+
{:erlang, :byte_size, [{[binary()], integer()}]},
376+
{:erlang, :ceil, [{[union(integer(), float())], integer()}]},
377+
{:erlang, :div, [{[integer(), integer()], integer()}]},
378+
{:erlang, :floor, [{[union(integer(), float())], integer()}]},
379+
{:erlang, :function_exported, [{[atom(), atom(), integer()], boolean()}]},
367380
{:erlang, :integer_to_binary, [{[integer()], binary()}]},
368381
{:erlang, :integer_to_binary, [{[integer(), integer()], binary()}]},
369382
{:erlang, :integer_to_list, [{[integer()], non_empty_list(integer())}]},
370383
{:erlang, :integer_to_list, [{[integer(), integer()], non_empty_list(integer())}]},
384+
{:erlang, :is_atom, is_clauses},
385+
{:erlang, :is_binary, is_clauses},
386+
{:erlang, :is_bitstring, is_clauses},
387+
{:erlang, :is_boolean, is_clauses},
388+
{:erlang, :is_float, is_clauses},
389+
{:erlang, :is_function, is_clauses},
390+
{:erlang, :is_function, [{[term(), integer()], boolean()}]},
391+
{:erlang, :is_integer, is_clauses},
392+
{:erlang, :is_list, is_clauses},
393+
{:erlang, :is_map, is_clauses},
394+
{:erlang, :is_map_key, [{[term(), open_map()], boolean()}]},
395+
{:erlang, :is_number, is_clauses},
396+
{:erlang, :is_pid, is_clauses},
397+
{:erlang, :is_port, is_clauses},
398+
{:erlang, :is_reference, is_clauses},
399+
{:erlang, :is_tuple, is_clauses},
400+
{:erlang, :length, [{[list(term())], integer()}]},
371401
{:erlang, :list_to_atom, [{[list(integer())], atom()}]},
372402
{:erlang, :list_to_existing_atom, [{[list(integer())], atom()}]},
373403
{:erlang, :list_to_float, [{[non_empty_list(integer())], float()}]},
374404
{:erlang, :list_to_integer, [{[non_empty_list(integer())], integer()}]},
375405
{:erlang, :list_to_integer, [{[non_empty_list(integer()), integer()], integer()}]},
376-
{:erlang, :list_to_tuple, [{[list(term())], dynamic(open_tuple([], term()))}]},
406+
{:erlang, :list_to_tuple, [{[list(term())], dynamic(open_tuple([]))}]},
407+
{:erlang, :make_ref, [{[], reference()}]},
408+
{:erlang, :map_size, [{[open_map()], integer()}]},
409+
{:erlang, :node, [{[], atom()}]},
410+
{:erlang, :node, [{[pid() |> union(reference()) |> union(port())], atom()}]},
411+
{:erlang, :not, [{[atom([false])], atom([true])}, {[atom([true])], atom([false])}]},
412+
{:erlang, :rem, [{[integer(), integer()], integer()}]},
413+
{:erlang, :round, [{[union(integer(), float())], integer()}]},
377414
{:erlang, :self, [{[], pid()}]},
378415
{:erlang, :spawn, [{[fun()], pid()}]},
379416
{:erlang, :spawn, [{mfargs, pid()}]},
380417
{:erlang, :spawn_link, [{[fun()], pid()}]},
381418
{:erlang, :spawn_link, [{mfargs, pid()}]},
382419
{:erlang, :spawn_monitor, [{[fun()], tuple([reference(), pid()])}]},
383420
{:erlang, :spawn_monitor, [{mfargs, tuple([reference(), pid()])}]},
421+
{:erlang, :tuple_size, [{[open_tuple([])], integer()}]},
422+
{:erlang, :trunc, [{[union(integer(), float())], integer()}]},
384423

385424
# TODO: Replace term()/dynamic() by parametric types
386-
{:erlang, :delete_element,
387-
[{[integer(), open_tuple([], term())], dynamic(open_tuple([], term()))}]},
425+
{:erlang, :++, [{[list(term()), term()], dynamic(list(term(), term()))}]},
426+
{:erlang, :--, [{[list(term()), list(term())], dynamic(list(term()))}]},
427+
{:erlang, :delete_element, [{[integer(), open_tuple([])], dynamic(open_tuple([]))}]},
388428
{:erlang, :hd, [{[non_empty_list(term(), term())], dynamic()}]},
389-
{:erlang, :element, [{[integer(), open_tuple([], term())], dynamic()}]},
429+
{:erlang, :element, [{[integer(), open_tuple([])], dynamic()}]},
390430
{:erlang, :insert_element,
391-
[{[integer(), open_tuple([], term()), term()], dynamic(open_tuple([], term()))}]},
431+
[{[integer(), open_tuple([]), term()], dynamic(open_tuple([]))}]},
432+
{:erlang, :max, [{[term(), term()], dynamic()}]},
433+
{:erlang, :min, [{[term(), term()], dynamic()}]},
392434
{:erlang, :send, [{[send_destination, term()], dynamic()}]},
393-
{:erlang, :setelement,
394-
[{[integer(), open_tuple([], term()), term()], dynamic(open_tuple([], term()))}]},
435+
{:erlang, :setelement, [{[integer(), open_tuple([]), term()], dynamic(open_tuple([]))}]},
395436
{:erlang, :tl, [{[non_empty_list(term(), term())], dynamic()}]},
396-
{:erlang, :tuple_to_list, [{[open_tuple([], term())], dynamic(list(term()))}]}
437+
{:erlang, :tuple_to_list, [{[open_tuple([])], dynamic(list(term()))}]}
397438
] do
398-
[{args, _return} | _others] = clauses
439+
[arity] = Enum.map(clauses, fn {args, _return} -> length(args) end) |> Enum.uniq()
440+
true = Code.ensure_loaded?(mod) and function_exported?(mod, fun, arity)
399441

400-
defp remote(unquote(mod), unquote(fun), unquote(length(args))),
442+
defp remote(unquote(mod), unquote(fun), unquote(arity)),
401443
do: unquote(Macro.escape(clauses))
402444
end
403445

0 commit comments

Comments
 (0)