Dialyzer: why an empty map passes as for a non-empty

Does anybody have an idea why this will not pass a Dialyzer check

  @spec foo :: %{:a => any}
  def foo(), do: %{}

but this will, when IMO it should not.

  @spec foo :: %{atom() => any}
  def foo(), do: %{}

as in the latter one I am saying an atom key is required.


This is a shortcoming in dialyzer. Only singleton keys like :some_specific_atom or 1234 can be mandatory, non-singletons like atom() are always treated as optional. :confused:

See otp/erl_types.erl at f518b5d3a9bde82ebcd16697f01ed2fd1fcfd0cb · erlang/otp · GitHub


Too bad, then I cannot check for a non-empty map,
Thank you for the explanation and the reference

1 Like