1

I am trying to make my library(https://github.com/CrowdHailer/OK) for working with result tuples play nicely with dialyzer.

At them moment there is code that raises a nice error if incorrect data input is given. However dialyzer points out that this case is never needed. I still want to keep this error case. it's very helpful to explain the error to new users of the library but I want to make dialyzer ignore it.

quote location: :keep do
  case unquote(right) do
    {:ok, unquote(left)} ->
      unquote(expand_bindings(rest, yield_block, exception_clauses))

    {:error, reason} ->
      {:error, reason}

      case reason do
        unquote(exception_clauses)
      end

      # This block will never be called, as far as dialyzer is concerned
      # However I want to keep it for the cases when diayzer is not being used in the project
      return ->
        raise %OK.BindError{
          return: return,
          lhs: unquote(Macro.to_string(left)),
          rhs: unquote(Macro.to_string(right))
        }
  end
end

The source can be seen here https://github.com/CrowdHailer/OK/blob/431142204794e1702271c86d6594ce76b8978b57/lib/ok.ex#L512-L529

Peter Saxton
  • 3,848
  • 5
  • 25
  • 44
  • *it's very helpful to explain the error to new users of the library*--That's what comments/@doc are for. It makes no sense to keep an unreachable clause in your code for documentation purposes. And...what is that inner case statement? Is that pseudo code? – 7stud Aug 22 '18 at 21:44
  • The code is reachable, in the case that you break the spec. But experience says that many Elixir devs will use it in a way that is not per spec. And without running dialyzer my error will be the first thing they see – Peter Saxton Aug 22 '18 at 21:45
  • Regarding your comment that "the code is reachable, in case that you break the spec", it might be worth verifying your intuition with `dialyzer --no_spec`. – aronisstav Aug 27 '18 at 07:40

1 Answers1

1

Pass generated: true to quote:

quote location: :keep, generated: true do

That tells the compiler and dialyzer not to emit warnings for that code.

legoscia
  • 37,068
  • 22
  • 103
  • 148
  • How would I make that apply around just the last case clause – Peter Saxton Aug 23 '18 at 11:42
  • The best way I can think of is to quote the `return -> ...` clause separately with `generated: true` and assign it to a variable, and then insert it into the main quote like you did with `exception_clauses`. – legoscia Aug 23 '18 at 12:38