Dialyzer cannot recognize error in function using polymorphic types

Still passes, even with :underspec. Reverting back to the tuple {:some, t} didn’t make any difference.
While the email specifies in mathematical detail what underspec is supposed to do, I still cannot find a real life scenario where I would want to use it.

I do think you are correct in the sense that [] | [t, ...] is the issue. I don’t see how though, since [] means empty list, and [t, ....] means a list with at least 1 element.

In my code, nil is neither of those cases.

The following code does raise a warning though:

  @type option(t) :: some(t) | nothing
  @type some(t) :: [t, ...]
  @type nothing :: nil

  @spec validate_name(String.t()) :: option(String.t())
  def validate_name(name) do
    if String.length(name) > 0 do
      [name]
    else
      0
    end
  end

Warning

Extra type:
nil

Success typing:
[binary(), ...] | 0

But this is confusing. There is 1 path that leads to success. Dialyzer should not complain.
Yet, here it does because nil !== 0.