Skip to content
Permalink
Browse files

Ensure reproducible builds (boostrapping issue) (#9385)

During bootstrap, the generated AST for the `defexception` macro
does not include import metadata when calling to Kernel functions
without using the qualified name. That's not the case when the
Kernel is later recompiled.

When compiling the standard library, exceptions like
`FunctionClauseError` were generating different ASTs (different
metadata) depending on if they were compiled with the bootstrapped
Kernel or the later compiled one.
  • Loading branch information...
fertapric authored and josevalim committed Oct 5, 2019
1 parent 50caa25 commit 66ac6a3d8ad6424b627147ab40adb0e02646bc4c
Showing with 8 additions and 4 deletions.
  1. +8 −4 lib/elixir/lib/kernel.ex
@@ -4433,14 +4433,18 @@ defmodule Kernel do
defoverridable message: 1

@impl true
def exception(msg) when is_binary(msg) do
def exception(msg) when Kernel.is_binary(msg) do
exception(message: msg)
end
end

# TODO: Change the implementation on v2.0 to simply call Kernel.struct!/2
# Calls to Kernel functions must be fully-qualified to ensure
# reproducible builds; otherwise, this macro will generate ASTs
# with different metadata (:import, :context) depending on if
# it is the bootstrapped version or not.
@impl true
def exception(args) when is_list(args) do
def exception(args) when Kernel.is_list(args) do
struct = __struct__()
{valid, invalid} = Enum.split_with(args, fn {k, _} -> Map.has_key?(struct, k) end)

@@ -4451,9 +4455,9 @@ defmodule Kernel do
_ ->
IO.warn(
"the following fields are unknown when raising " <>
"#{inspect(__MODULE__)}: #{inspect(invalid)}. " <>
"#{Kernel.inspect(__MODULE__)}: #{Kernel.inspect(invalid)}. " <>
"Please make sure to only give known fields when raising " <>
"or redefine #{inspect(__MODULE__)}.exception/1 to " <>
"or redefine #{Kernel.inspect(__MODULE__)}.exception/1 to " <>
"discard unknown fields. Future Elixir versions will raise on " <>
"unknown fields given to raise/2"
)

0 comments on commit 66ac6a3

Please sign in to comment.
You can’t perform that action at this time.