Failing run dialyzer

Hi,

using elixir 1.12.x i have a compilation error running mix dialyzer and the problem seems to be the list of warning options passed to @dialyzer.

Using this sample module (just to force warnings), it is possible to reproduce it:

defmodule Sample do
  @dialyzer {[:no_return, :no_contracts, :no_fail_call], hello: 0}
  def hello do
    default("1", 1)
  end

  @spec default(binary, binary) :: binary
  def default(something, _something2) do
    case something do
      "1" -> "hello"
      _ -> raise "oops"
    end
  end
end

Running mix dialyzer:

== Compilation error in file lib/sample.ex ==
** (ArgumentError) invalid value for @dialyzer attribute: {[:no_return, :no_contracts, :no_fail_call], [hello: 0]}
    (elixir 1.12.3) lib/module.ex:2193: anonymous fn/1 in Module.preprocess_attribute/2
    (stdlib 3.14.2.2) lists.erl:1342: :lists.foreach/2
    (elixir 1.12.3) lib/module.ex:2190: Module.preprocess_attribute/2
    (elixir 1.12.3) lib/module.ex:2022: Module.__put_attribute__/4
    lib/sample.ex:2: (module)

With elixir 1.11.x, the code compiles successfully.

Am i wrong something?

1 Like

I’m also seeing this after attempting to upgrade Phoenix from 1.6 to 1.7.

The @spec (but not the code) for Phoenix.Controller.put_layout was changed in a non-backwards compatible way, which causes dialyzer to fail with:

Phoenix.Controller.put_layout(...)
breaks the contract
(Plug.Conn.t(), [{format :: atom(), layout()}]) :: Plug.Conn.t()

However, attempting to ignore this doesn’t seem to work:

defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller

  # undefined function put_layout/2 given to @dialyzer
  @dialyzer {:nowarn_function, put_layout: 2}
  plug :put_layout, {MyAppWeb.LayoutView, "page.html"}

  #(ArgumentError) invalid value for @dialyzer attribute: {:nowarn_function, &Phoenix.Controller.put_layout/2}
  @dialyzer {:nowarn_function, &put_layout/2}
  plug :put_layout, {MyAppWeb.LayoutView, "page.html"}