In one of my libs I add type information such as @type routes :: [Phoenix.Router.Route.t()]
This causes mix docs to throw warnings as the module (not the type) is hidden via @moduledoc false
warning: documentation references type "Phoenix.Router.Route.t()" but the module Phoenix.Router.Route is hidden
│
17 │ @type routes :: [Phoenix.Router.Route.t()]
│ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
│
└─ lib/routex/extension.ex:17: Routex.Extension (module)
Partial solution
In a related Github issue the users works around the module being hidden, by setting skip_undefined_reference_warnings_on. So I applied the same solution.
How are you getting access to private structs? Why do you need to interact with them? Generally the solution would be to not depend on things you’re not expected to depend on.
I use the typing as Phoenix.Router.Route’s are the input and output of the middleware.
The type is quite literally the only ‘dependency’ the lib has and all red flags should raise when the contract is broken. It is also an @type not an @typep (not even @opaque).
That would to be a convention unknown to me (as a workaround?) rather than a strict behavior as far as I can tell. From the docs
Conveniently, Elixir allows developers to hide modules and functions from the documentation, by setting @doc false to hide a particular function, or @moduledoc false to hide the whole module.
However, keep in mind @moduledoc false or @doc false do not make a function private.
So according to the official documentation, the modules hides documentation but includes a public type.
This could make sense: You are not discouraged to rely on functions in the submodule Route, but is is also the best place to specify the struct and the type.
Nope, this is pre-1.18 behavior. I ignored the warnings for a long time as I was aware they were only emitted by ExDocs. Dialyzer uses the type information without issues afaik. After all, types are mainly used for automated checks not as documentation for humans.
So to summarize:
ExDocs warns because it does not want to link to an undocumented type / non-existing page. (works)
Not linking can be done with :skip_code_autolink_to(works)
Referencing in docs (@doc or .md) should cause a warning (works)
Referencing an @type in @type should just work* (fails, causes warning in ExDoc)
You cannot just rely on defp/@typep for project level privacy. They only help with the module level. The convention of using @moduledoc false has been used for a long time in elixir itself and many 3rd party projects to define what is meant to be the public api or not.