How to interpret a guarded return value in a function specification?

The init/1 callback from GenServer has this specification:

@callback init(init_arg :: term()) ::
  {:ok, state}
  | {:ok, state, timeout() | :hibernate | {:continue, continue_arg :: term()}}
  | :ignore
  | {:stop, reason :: term()}
when state: term()

What does the last line mean? Going off intuition alone I would assume that the above spec is equivalent to:

@callback init(init_arg :: term()) ::
  {:ok, state :: term()}
  | {:ok, state :: term(), timeout() | :hibernate | {:continue, continue_arg :: term()}}
  | :ignore
  | {:stop, reason :: term()}

But the typespecs reference only mentions guards that restrict the types of the arguments given to the function. In fact, it seems like it says the opposite:

  • Guards can be used to restrict type variables given as arguments to the function.

To me, it sounds like this sentence specifically precludes the possibility of using a guard to restrict the type of the value returned by the function. Is the documentation just outdated?

Yes, you are correct. It used to indicate that input or output doesn’t change. For example

@spec wrap(x) :: {:ok, x} when x: term()
def wrap(x), do: {:ok, x}