Originally reported in ExDoc.
https://github.com/elixir-lang/ex_doc/issues/1239
Code.Typespec.spec_to_quoted/2 wouldn't know how to deal with a
map with __struct__ key that is not a module, such as in:
@spec foo(%{__struct__: Foo | Bar}) :: any()
Atoms that have non-ascii characters or @ does not
require tokens. That's to streamline the developer
experience around examples :"foo@computer-name" and
:"hélló".
These tests actually use get_and_update_in/3 and pop_in/2.
I removed the arities, rather than correcting them, since it seems
like unnecessary detail here.
This augments the Calendar behaviour by adding
a new function, c:Calendar.day_of_week/4 which
supports a starting_on value with defaults and
calendar specific semantics.
For example, in Plug, you might see:
[profile] lib/plug/conn.ex compiled in 935ms
[profile] lib/plug/ssl.ex compiled in 147ms (plus 744ms waiting)
[profile] lib/plug/static.ex compiled in 238ms (plus 654ms waiting)
[profile] lib/plug/csrf_protection.ex compiled in 237ms (plus 790ms waiting)
[profile] lib/plug/debugger.ex compiled in 719ms (plus 947ms waiting)
[profile] Finished compilation cycle of 60 modules in 1802ms
[profile] Finished group pass check of 60 modules in 75ms
This commit also increases the precision of --long-compilation-threshold
which now tracks only the time spent compiling and not the time waiting.
For this reason, we have reduced the threshold time to 10 seconds.
Previously, imports and requires were always added as
compile-time dependencies. With this change, they are
"export" dependencies, which are dependencies that depend
on the API defined by a module, such as struct and its
public definitions.
This change should drastically remove the amount of
modules recompiled in Elixir, making imports more feasible
for large projects.
We also don't hardcode the RELEASE_MODE config variable
inside Config.Provider, instead we use the application
environment. To make this possible, we simplify the boot
signature for the provider so it only calls boot/0 instead
of a dynamic app-key pair.
The dependency doesn't seem needed in this case.
We go through extra hoops to maintain dynamic invocations where
`opts` is not a compile-time list and :to is not a literal.
An easy way to see this optimization is:
defmodule A do
defdelegate f(), to: B
end
defmodule B do
def f() do
:ok
end
end
$ touch lib/b.ex && mix compile --verbose
Compiling 1 file (.ex)
Compiled lib/b.ex
vs:
defmodule A do
opts = [to: B]
defdelegate f(), opts
end
defmodule B do
def f() do
:ok
end
end
$ touch lib/b.ex && mix compile --verbose
Compiling 2 files (.ex)
Compiled lib/b.ex
Compiled lib/a.ex