josefs / Gradualizer

A Gradual type system for Erlang
MIT License
612 stars 35 forks source link

Missing optional map keys raise errors #297

Open haljin opened 3 years ago

haljin commented 3 years ago

Hi,

I have an Elixir application where a GenServer defines a custom child_spec function as follows:

  @spec child_spec(readacted()) :: Supervisor.child_spec()
  def child_spec([...]) do
    %{
      id: __MODULE__,
      type: :supervisor,
      start:
        {<redacted>, :start_link,
         [
           [
             ...
             ]
           ]
         ]}
    }
  end

This causes gradualizer to complain about:

....beam: The map on line 30 is expected to have type 'Elixir.Supervisor':child_spec() but it has type #{id := 'Elixir.<redacted>,
            type := supervisor,
            start :=
                {'Elixir.<redacted.', start_link,
                 [[
                   ...],
                  ...]}}

When I add all the optional keys:

  @spec child_spec(readacted()) :: Supervisor.child_spec()
  def child_spec([...]) do
    %{
      id: __MODULE__,
      type: :supervisor,
      restart: :permanent,
      shutdown: 5000,
      modules: [],
      start:
        {<redacted>, :start_link,
         [
           [
             ...
             ]
           ]
         ]}
    }
  end

the warning goes away. These keys are marked as optional according to https://hexdocs.pm/elixir/Supervisor.html#t:child_spec/0

Am I doing something wrong or does gradualizer not handle optional keys in maps?

zuiderkwast commented 3 years ago

Thanks for the report! I think you're right and Gradualizer is wrong. Gradualizer is not very good at maps yet.