Elixir allows Map functions to manipulate structs

As I’ve written above, dialyzer errors properly on Map.put/3, guarding structs if you do use typespecs…

…However noticed that Map.delete/2 would still pass, even if the required key defined in the struct typespec is missing :thinking:

Example, the below returns an empty map after all, and still passes as it’s returning a t:

  @spec foo() :: t
  def foo do
    %__MODULE__{
      a: 1,
      b: "aha",
      c: :foo
    }
    |> Map.delete(:a)
    |> Map.delete(:b)
    |> Map.delete(:c)
    |> Map.delete(:__struct__)
  end

It isn’t a struct specific issue, a simple map also has the same issue (no errors):

  @spec foo() :: %{required(:a) => non_neg_integer()}
  def foo do
    %{a: 1}
    |> Map.delete(:a)
  end

I think it is a dialyzer bug, let’s see with the OTP guys what this behaviour turns out to be, bug or feature :stuck_out_tongue:

https://bugs.erlang.org/browse/ERL-1002

3 Likes