witchcrafters / witchcraft

Monads and other dark magic for Elixir
https://witchcrafters.github.io
MIT License
1.2k stars 58 forks source link

`use Witchcraft` fails when excepting functions defined in `Kernel` #93

Closed florius0 closed 3 years ago

florius0 commented 3 years ago

When trying to import Witchcraft without some functions that are also defined in Kernel module, compile error occurs:

iex(1)> use Witchcraft, except: [<>: 2]
** (CompileError) iex:19: invalid :except option for import, <>/2 is duplicated
    (stdlib 3.16.1) lists.erl:1267: :lists.foldl/3
    (elixir 1.12.3) src/elixir_import.erl:74: :elixir_import.calculate/6
    (elixir 1.12.3) src/elixir_import.erl:24: :elixir_import.import/4
    (witchcraft 1.0.3) expanding macro: Witchcraft.Semigroup.__using__/1
    iex:19: (file)
iex(1)>

After brief investigation it appears that in every __using__ macro like this in new_opts there is a duplicate of excepted function, which should be removed instead.

defmacro __using__(opts \\ []) do
  {:ok, new_opts} =
    Keyword.get_and_update(opts, :except, fn except ->
      {:ok, [<>: 2] ++ (except || [])}
    end)

  if Access.get(opts, :override_kernel, true) do
    quote do
      import Kernel, unquote(new_opts)
      import unquote(__MODULE__), unquote(opts)
    end
  else
    quote do: import(unquote(__MODULE__), unquote(new_opts))
  end
end
github-actions[bot] commented 3 years ago

Thank you for submitting an issue! It means a lot that you took the time -- it helps us be better 🙏

florius0 commented 3 years ago

This issue is fixed in #83