The guard clause: when _ :: [any()] === nil can never succeed

Hey all,
noob alert.

I have recently started with Elixir and Phoenix. Trying a simple web app with some forms. I have following code in one of my html helper module.

def input(form, field, opts \\ []) do
  type = Phoenix.HTML.Form.input_type(form, field)

  wrapper_classes = Keyword.get_values(opts, :wrapper_class) ++ ["flex", "flex-col", "pt-4"]
  inputs_classes = Keyword.get_values(opts, :input_class) ++ ["shadow", "appearance-none", "border", "rounded", "w-full", "py-2", "px-3", "text-gray-700", "mt-1", "leading-tight", "focus:outline-none", "focus:shadow-outline"]
    ++ if form.errors[field], do: ["border-red-500"], else: []

  wrapper_opts = [class: Enum.join(wrapper_classes, " ")]

  is_required = input_validations(form, field) |> Keyword.get(:required)
  input_opts =
    [class: Enum.join(inputs_classes, " ")] ++
      Keyword.drop(opts, [:wrapper_class, :input_class]) ++
      if is_required, do: [required: "required"], else: []

  label = (Keyword.get(opts, :label) || humanize(field)) <> if is_required, do: " *", else: ""

  content_tag :div, wrapper_opts do
    [
      label(form, field, label, class: "text-lg"),
      content_tag :div do
        input = apply(Phoenix.HTML.Form, type, [form, field, input_opts])
        error = MyAppWeb.ErrorHelpers.error_tag(form, field)
        [input, error || ""]
      end
    ]
  end
end

In above code ElixirLS Dialyzer gives following warning for line [input, error || ""]

The guard clause:

when _ :: [any()] === nil

can never succeed.

May be i am doing something wrong here. Any inputs would be appreciated. Also ways to improve above code would be appreciated.

Dialyzer infers that error is always a list, therefore it tells you, that error || "" will never give you anything but errors value.

1 Like

Thanks @NobbZ for the quick reply. I changed it to

[input, (if error==[], do: "", else: error)]

And the warning is no more. Is this the correct way or do you recommend some other way?

I’d probably use an intermediate binding and Enum.empty?/1, but seems to be one of the ways.