Reason to add it is capturing functions when passing in module name,
function name and arity using variable, because the capture operator
can't handle them.
Done by delegating to `:erlang.make_fun(mod, f, arity)`, also exposed
some erlang functions for getting information for a function.
This avoids copying typespecs in and out of the table
every time there is a new entry.
We also make sure the Protocol module is only relying
on public APIs and not on inner typespec behaviour.
Previously we kept a Set table for attributes and a Bag table
for function definitions and clauses. This led to suboptimal
usage of ets tables.
With this commit, we start using both Bag and Set tables
to store function/macro definition information. In the next
commits we will continue generalizing the tables, storing
specs, docs and accumulated attributes in the Bag and keep
the remaining functionality in Set.
Kernel.Typespec will be responsible for handling typespec
logic during compilation, such as definitions, conversion to
Erlang and warnings. Its API shall never be public.
Code.Typespec will handle the runtime aspects, such as reading
from .beam files and conversion back to Elixir AST. Its API
may be made public in the future but it is currently private.
This PR also simplifies definition of typespecs internally by
avoiding multiple macro passes and speeds up typespec processing
on OTP 20+ by skipping the translation pass from Elixir to Erlang.
The test suite was also reorganized and made async: true.
The :timed_out message was not cancelled properly when compilation failed in ParallelCompiler. This meant the timeout message would be delivered even after compilation completed. This could be problematic when invoking compilation programmatically via e.g. Mix.Task.run("compile", ["--return-errors"]) since it means that the calling process, depending on the implemenation, might crash unexpectedly or get its inbox filled with messages.
The fix simply calls the cancel_waiting_timer when a compilation error has ocurred in the same way it is called in other similar cases.
Not all calendars have a constant 12 months in
a year. This function returns the number of
months for a given year. Calendar.ISO will return
12 for all years.
Add Date.days_in_month/1
Date.days_in_month/1 takes a Date.t and
delegates to the Date's calendar to invoke
days_in_month/1 in the calendar module.