Example module with a function with a private function not called by a public function:
defmodule Specs do
@type network :: :mainnet | :testnet3
@spec magic(network) :: binary
defp magic(:mainnet) do
<<0xf9,0xbe,0xb4,0xd9>>
end
defp magic(:testnet3) do
<<0x0b, 0x11, 0x09, 0x07>>
end
end
The error in iex:
iex(1)> c "defp.ex"
defp.ex:4: warning: function magic/1 is unused
== Compilation error on file defp.ex ==
** (CompileError) defp.ex:3: spec for undefined function Specs.magic/1
(stdlib) lists.erl:1336: :lists.foreach/2
(stdlib) erl_eval.erl:657: :erl_eval.do_apply/6
** (exit) shutdown: 1
(elixir) lib/kernel/parallel_compiler.ex:199: Kernel.ParallelCompiler.handle_failure/5
(elixir) lib/kernel/parallel_compiler.ex:182: Kernel.ParallelCompiler.wait_for_messages/8
(elixir) lib/kernel/parallel_compiler.ex:55: Kernel.ParallelCompiler.spawn_compilers/3
(iex) lib/iex/helpers.ex:94: IEx.Helpers.c/2
From what I have seen in the source code of elixir, @spec is written for public methods and not private ones. So I think, it's by design.
No, you can write @spec for private functions. This is a bug in the Elixir compiler because, if you write a private function that is never invoked, we remove it from source, causing it to fail. We likely should remove the unused spec definitions too.
@josevalim can you please point to where the unused private function get removed in the src? I searched (and grepped) through the src and could go only so far as to find locals_tracker.ex collecting the unused defs to display in warnings but couldn't find out where they are removed.
@shankardevy I believe this is where they're filtered out: https://github.com/elixir-lang/elixir/blob/master/lib/elixir/src/elixir_def.erl#L210-L276 (253-262 in particular). Not sure where the specs are handled.
[UPDATED: specs seem to be handled in elixir_module.erl]
@shankardevy Are you working on this issue? I was thinking I'd give it a go, but I thought to ask first, to avoid the duplication of effort if you already were.
Sorry @oneeman , didn't notice your message. Thanks for asking. I see you have already completed while I was nowhere near ;-)
No problem :-)
Most helpful comment
No, you can write @spec for private functions. This is a bug in the Elixir compiler because, if you write a private function that is never invoked, we remove it from source, causing it to fail. We likely should remove the unused spec definitions too.