Dialyzer error coming from macro definition/expansion

Using ElixirLS with vscode, I’m getting the error/warning below on this file in my project:

https://github.com/CharlesIrvineKC/mozart/blob/main/lib/processes/home_loan_app.ex

The error is:

The guard clause:

when _ ::
  %Mozart.Data.BpmApplication{
    :bk_prefix => [<<_::64, _::size(8)>>, ...],
    :data => [<<_::32, _::size(8)>>, ...],
    :groups => [<<_::48, _::size(16)>>, ...],
    :module => Opera.Processes.HomeLoanApp,
    :process => <<_::72>>
  } === nil

can never succeed.
ElixirLS Dialyzer
Kernel.defmodule(alias, do_block)

The error is referring to this macro call:

  def_bpm_application("Home Loan",
    data: "First Name,Last Name,Income,Debt",
    bk_prefix: "Last Name, First Name"
  )

As far as I can tell, all of the code in the project is working as expected, i.e. there doesn’t seem to really be a problem.

My problem at this point is that I don’t what the error means, since the guard clause mentioned is not explicitly in my code.

Could someone give me a nudge in the right direction? Thanks

Usually the solution is to not generate the unnecessary comparison in the first place. E.g. instead of:

def maybe(b), do: @compile_time == nil

you’d do:

if @compile_time == nil do
  def maybe(b), do: true
else
  def maybe(b), do: false
end
# or
def maybe(b), do: unquote(@compile_time == nil)

Sorry. That went over my head. What comparison are you referring to?

Your macro generates some code. All dialyzer gets to see is that generated code. Somewhere in there is a check for data potentially being nil, but that data seems to be statically defined as a struct. So the comparison doesn’t make sense because the hardcoded data can never be nil. The solution would be changing the code the macro generates to not include that check if the data is that struct (and known to be that at compile time).

2 Likes

That helped me track down and fix the problem. Thanks